kodi_client 0.6.3 → 0.6.4
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/kodi_client.gemspec +1 -1
- data/lib/kodi_client/extensions/chainable.rb +71 -0
- data/lib/kodi_client/extensions/comparable.rb +29 -0
- data/lib/kodi_client/extensions/creatable.rb +137 -0
- data/lib/kodi_client/extensions/iterable.rb +14 -0
- data/lib/kodi_client/kodi_error.rb +14 -0
- data/lib/kodi_client/kodi_method.rb +34 -0
- data/lib/kodi_client/{options.rb → kodi_options.rb} +1 -1
- data/lib/kodi_client/kodi_request.rb +16 -0
- data/lib/kodi_client/kodi_response.rb +21 -0
- data/lib/kodi_client/{method → methods}/addons.rb +4 -4
- data/lib/kodi_client/{method → methods}/application.rb +2 -2
- data/lib/kodi_client/{method → methods}/audio_library.rb +2 -2
- data/lib/kodi_client/{method → methods}/favourites.rb +2 -2
- data/lib/kodi_client/{method → methods}/files.rb +2 -2
- data/lib/kodi_client/{method → methods}/gui.rb +2 -2
- data/lib/kodi_client/{method → methods}/input.rb +2 -2
- data/lib/kodi_client/{method → methods}/player.rb +2 -2
- data/lib/kodi_client/{method → methods}/profiles.rb +2 -2
- data/lib/kodi_client/{method → methods}/system.rb +2 -2
- data/lib/kodi_client/types/addons/addon_content_type.rb +18 -0
- data/lib/kodi_client/types/addons/addon_dependency_type.rb +21 -0
- data/lib/kodi_client/types/addons/addon_details_type.rb +44 -0
- data/lib/kodi_client/types/addons/addon_extra_info_type.rb +20 -0
- data/lib/kodi_client/types/addons/addon_fields_type.rb +28 -0
- data/lib/kodi_client/types/addons/addon_types_type.rb +48 -0
- data/lib/kodi_client/types/addons/get_addon_returned_type.rb +21 -0
- data/lib/kodi_client/types/addons/get_addons_returned_type.rb +22 -0
- data/lib/kodi_client/types/application/property_name_type.rb +19 -0
- data/lib/kodi_client/types/application/property_value_type.rb +24 -0
- data/lib/kodi_client/types/application/version_type.rb +22 -0
- data/lib/kodi_client/types/audio/audio_album_release_type_type.rb +15 -0
- data/lib/kodi_client/types/audio/audio_contributor_type.rb +22 -0
- data/lib/kodi_client/types/audio/audio_details_base_type.rb +31 -0
- data/lib/kodi_client/types/audio/audio_details_media_type.rb +45 -0
- data/lib/kodi_client/types/audio/audio_fields_album_type.rb +51 -0
- data/lib/kodi_client/types/audio/details_album_type.rb +58 -0
- data/lib/kodi_client/types/audio/genre_type.rb +20 -0
- data/lib/kodi_client/types/audio/get_albums_returned_type.rb +22 -0
- data/lib/kodi_client/types/favourites/details_favourite_type.rb +24 -0
- data/lib/kodi_client/types/favourites/fields_favourite_type.rb +17 -0
- data/lib/kodi_client/types/favourites/get_favourite_returned_type.rb +22 -0
- data/lib/kodi_client/types/favourites/type_type.rb +18 -0
- data/lib/kodi_client/types/files/file_label_type.rb +20 -0
- data/lib/kodi_client/types/files/get_directory_returned_type.rb +22 -0
- data/lib/kodi_client/types/files/get_sources_returned_type.rb +22 -0
- data/lib/kodi_client/types/files/media_type.rb +18 -0
- data/lib/kodi_client/types/files/prepare_download_returned_type.rb +21 -0
- data/lib/kodi_client/types/global/direction_type.rb +17 -0
- data/lib/kodi_client/types/global/global_time_type.rb +22 -0
- data/lib/kodi_client/types/global/id_label_type.rb +20 -0
- data/lib/kodi_client/types/global/id_name_type.rb +20 -0
- data/lib/kodi_client/types/global/increment_decrement_type.rb +15 -0
- data/lib/kodi_client/types/global/next_prev_type.rb +17 -0
- data/lib/kodi_client/types/global/password_encryption_type.rb +16 -0
- data/lib/kodi_client/types/global/rotate_type.rb +15 -0
- data/lib/kodi_client/types/global/toggle_type.rb +16 -0
- data/lib/kodi_client/types/gui/gui_window_type.rb +124 -0
- data/lib/kodi_client/types/gui/property_name_type.rb +18 -0
- data/lib/kodi_client/types/gui/property_value_type.rb +26 -0
- data/lib/kodi_client/types/gui/stereoscopy_mode_type.rb +31 -0
- data/lib/kodi_client/types/input/input_action_type.rb +212 -0
- data/lib/kodi_client/types/{item_types.rb → items/item_details_base_type.rb} +1 -3
- data/lib/kodi_client/types/list/list_field_files_type.rb +83 -0
- data/lib/kodi_client/types/list/list_fields_all_type.rb +96 -0
- data/lib/kodi_client/types/list/list_item_all_type.rb +73 -0
- data/lib/kodi_client/types/list/list_item_base_type.rb +138 -0
- data/lib/kodi_client/types/list/list_item_file_type.rb +68 -0
- data/lib/kodi_client/types/list/list_limits_returned_type.rb +23 -0
- data/lib/kodi_client/types/list/list_limits_type.rb +19 -0
- data/lib/kodi_client/types/list/list_sort_method_type.rb +54 -0
- data/lib/kodi_client/types/list/list_sort_type.rb +22 -0
- data/lib/kodi_client/types/list/sort_order_type.rb +15 -0
- data/lib/kodi_client/types/media/media_artwork_type.rb +22 -0
- data/lib/kodi_client/types/media/media_details_base_type.rb +28 -0
- data/lib/kodi_client/types/media/media_type_type.rb +16 -0
- data/lib/kodi_client/types/player/audio_stream_type.rb +29 -0
- data/lib/kodi_client/types/player/player_position_time_type.rb +22 -0
- data/lib/kodi_client/types/player/player_repeat_type.rb +17 -0
- data/lib/kodi_client/types/player/player_speed_type.rb +26 -0
- data/lib/kodi_client/types/player/player_type.rb +24 -0
- data/lib/kodi_client/types/player/player_type_type.rb +16 -0
- data/lib/kodi_client/types/player/player_view_mode_type.rb +23 -0
- data/lib/kodi_client/types/player/player_visibility_type.rb +16 -0
- data/lib/kodi_client/types/player/property_name_type.rb +38 -0
- data/lib/kodi_client/types/player/property_value_type.rb +60 -0
- data/lib/kodi_client/types/player/seek_jump_type.rb +17 -0
- data/lib/kodi_client/types/player/seek_returned_type.rb +23 -0
- data/lib/kodi_client/types/player/subtitle_type.rb +24 -0
- data/lib/kodi_client/types/player/video_stream_type.rb +26 -0
- data/lib/kodi_client/types/player/view_mode_type.rb +22 -0
- data/lib/kodi_client/types/player/zoom_type.rb +15 -0
- data/lib/kodi_client/types/profiles/details_profile_type.rb +24 -0
- data/lib/kodi_client/types/profiles/fields_profile_type.rb +15 -0
- data/lib/kodi_client/types/profiles/get_profiles_returned_type.rb +22 -0
- data/lib/kodi_client/types/profiles/profile_password_type.rb +20 -0
- data/lib/kodi_client/types/{pvr_type.rb → pvr/channel_type_type.rb} +2 -4
- data/lib/kodi_client/types/system/property_name_type.rb +17 -0
- data/lib/kodi_client/types/{system_types.rb → system/property_value_type.rb} +2 -13
- data/lib/kodi_client/types/video/stream_details_type.rb +24 -0
- data/lib/kodi_client/types/video/video_cast_type.rb +22 -0
- data/lib/kodi_client/types/video/video_details_base_type.rb +29 -0
- data/lib/kodi_client/types/video/video_details_file_type.rb +37 -0
- data/lib/kodi_client/types/video/video_details_item_type.rb +32 -0
- data/lib/kodi_client/types/video/video_details_media_type.rb +28 -0
- data/lib/kodi_client/types/video/video_resume_type.rb +20 -0
- data/lib/kodi_client.rb +137 -49
- metadata +107 -34
- data/lib/kodi_client/Chainable.rb +0 -48
- data/lib/kodi_client/kodi_module.rb +0 -80
- data/lib/kodi_client/types/addon_types.rb +0 -177
- data/lib/kodi_client/types/application_types.rb +0 -52
- data/lib/kodi_client/types/audio_types.rb +0 -221
- data/lib/kodi_client/types/favourites_types.rb +0 -61
- data/lib/kodi_client/types/files_types.rb +0 -63
- data/lib/kodi_client/types/global_types.rb +0 -102
- data/lib/kodi_client/types/gui_types.rb +0 -179
- data/lib/kodi_client/types/input_types.rb +0 -214
- data/lib/kodi_client/types/list_types.rb +0 -542
- data/lib/kodi_client/types/media_types.rb +0 -53
- data/lib/kodi_client/types/player_type.rb +0 -294
- data/lib/kodi_client/types/profiles_types.rb +0 -65
- data/lib/kodi_client/types/video_types.rb +0 -150
- data/lib/kodi_client/util/comparable.rb +0 -20
- data/lib/kodi_client/util/creatable.rb +0 -106
- data/lib/kodi_client/util/iterable.rb +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a3459e42458d3c4ec86456bd1e5ab18261a636ca9a61a48b6d2db3dbb0706b72
|
|
4
|
+
data.tar.gz: a1c20cd980f8c5c63fe69652e737495313110268b184cf2b58cf88ff850908b4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 707936b7399a44bb81e2a8efe79700c4267f74ed9f1307503d7f073ac1111b929169cb90bf412cfd615881cd0d92e06e044d4acb09930a059d3b09cfcfd3b215
|
|
7
|
+
data.tar.gz: 0c5779c4534c5b8a65d571764d0ecfb4cfb1defbc868c499cc977a98783f095fcd96ecf2a829e0fa278565c46e91eb312647b2ab5933f92e4fe19d4a257f7898
|
data/.rubocop.yml
CHANGED
data/kodi_client.gemspec
CHANGED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
module Extensions
|
|
5
|
+
# Offers methods like connect, auth and tls to be chained together
|
|
6
|
+
module Chainable
|
|
7
|
+
|
|
8
|
+
attr_accessor :options, :client
|
|
9
|
+
|
|
10
|
+
# Creates a new Client instance and sets the given ip and port to connect to it
|
|
11
|
+
# @param ip [String] the ip to use
|
|
12
|
+
# @param port [Integer] the port to connect to
|
|
13
|
+
# @raise [ArgumentError] thrown if ip or port is nil
|
|
14
|
+
# @return [Client] the created client
|
|
15
|
+
def connect(ip, port)
|
|
16
|
+
throw ArgumentError('ip or port can\'t be nil.') if ip.nil? || port.nil?
|
|
17
|
+
@client = KodiClient::Client.new
|
|
18
|
+
merge_options(->(options) { options.with_connection(ip, port) })
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# sets username and password if required
|
|
22
|
+
# @param username [String] the username
|
|
23
|
+
# @param password [String] the password
|
|
24
|
+
# @return [Client] the existing, or if not existed, a new created client
|
|
25
|
+
def auth(username, password)
|
|
26
|
+
throw ArgumentError('username or password can\'t be nil.') if username.nil? || password.nil?
|
|
27
|
+
merge_options(->(options) { options.with_auth(username, password) })
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# enables/disables the use of TLS
|
|
31
|
+
# @param enabled [Boolean] true to enable it, false to disable
|
|
32
|
+
# @return [Client] the existing, or if not existed, a new created client
|
|
33
|
+
def use_tls(enabled: true)
|
|
34
|
+
merge_options(->(options) { options.with_tls(enabled) })
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# merges the existing options with the new options
|
|
38
|
+
# @param [Proc] set_command so command to execute on the existing options to merge them
|
|
39
|
+
# @return [Client] the existing, or if not existed, a new created client
|
|
40
|
+
def merge_options(set_command)
|
|
41
|
+
client = def_client
|
|
42
|
+
options = def_options
|
|
43
|
+
set_command.call(options)
|
|
44
|
+
client.apply_options_to_methods(options)
|
|
45
|
+
client
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Creates a new, or if one already exists, returns the existing client
|
|
49
|
+
# @return [Client] the new or existing client
|
|
50
|
+
def def_client
|
|
51
|
+
if @client.nil?
|
|
52
|
+
@client = KodiClient::Client.new
|
|
53
|
+
@client.client = @client
|
|
54
|
+
end
|
|
55
|
+
@client
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Creates a new, or if one already exists, returns the existing Options
|
|
59
|
+
# @return [KodiOptions] the new or existing Options
|
|
60
|
+
def def_options
|
|
61
|
+
if @options.nil?
|
|
62
|
+
@options ||= KodiClient::KodiOptions.new
|
|
63
|
+
@client.options = @options
|
|
64
|
+
end
|
|
65
|
+
@options
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private :def_client, :def_options, :merge_options
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
module Extensions
|
|
5
|
+
# offers compare methods
|
|
6
|
+
module Comparable
|
|
7
|
+
|
|
8
|
+
# compares the instance variables of 2 objects for equality
|
|
9
|
+
# @param obj1 object 1
|
|
10
|
+
# @param obj2 object 2
|
|
11
|
+
# @return [Boolean] true if both instance variables are the same, else false
|
|
12
|
+
def compare(obj1, obj2)
|
|
13
|
+
is_same = true
|
|
14
|
+
obj1.instance_variables.each do |it|
|
|
15
|
+
is_same = false if obj1.instance_variable_get(it) != obj2.instance_variable_get(it)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
is_same
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# compares all Comparables using the defined compare method
|
|
22
|
+
# @param other [Object] the object to compare with
|
|
23
|
+
# @return [Boolean] true if equal, else false
|
|
24
|
+
def ==(other)
|
|
25
|
+
compare(self, other)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
module Extensions
|
|
5
|
+
# creates a create and create_list method by hash
|
|
6
|
+
module Creatable
|
|
7
|
+
|
|
8
|
+
# sets the fields to fetch from the given hash for the #create method. This is optional and only to use, if
|
|
9
|
+
# more fields should be fetched than are provided using attr_reader
|
|
10
|
+
# @param [Array<String>] fields the fields given as a string array
|
|
11
|
+
def fields_to_map(fields)
|
|
12
|
+
@fields_to_map = fields
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# defines mappings in case an attribute in the hash is not primitive and requires further processing. The argument
|
|
16
|
+
# is an Array of Arrays. Each array contains ['field_name', [type_to_map_to], [opt if field is a list]]
|
|
17
|
+
# @param args [Array<Array>] mappings. Example mapping ['art', Media::ArtWork, true], in this case
|
|
18
|
+
# Media::ArtWork.create_list will be called
|
|
19
|
+
def type_mapping(*args)
|
|
20
|
+
return if args.nil?
|
|
21
|
+
|
|
22
|
+
@type_mapping = {}
|
|
23
|
+
args.map { |it| @type_mapping[it[0]] = Creatable::CreateMap.new(it[1], it[2].nil? ? false : it[2]) }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# if @type_mapping is nil, it tries to fetch the mapping from here instead
|
|
27
|
+
# @return [Hash<String, CreateMap>] an hash containing all the mappings
|
|
28
|
+
def lazy_type_mapping
|
|
29
|
+
{}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# expects the given hash is a list of hashes and calls #create on each element
|
|
33
|
+
# @param [Array<Hash>] hash given list of hashes
|
|
34
|
+
# @return [Array] empty if hash is nil, otherwise array containing the elements
|
|
35
|
+
def create_list(hash)
|
|
36
|
+
hash.nil? ? [] : hash.map { |it| create(it) }.reject(&:nil?)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# creates a Creatable using the provided hash and the attr_reader fields, or if given #fields_to_map instead
|
|
40
|
+
# The parameters will be passed to initialize the object in the same order as they are passed to attr_reader
|
|
41
|
+
# or #fields_to_map
|
|
42
|
+
# @param hash [Hash] the given hash to convert to an object
|
|
43
|
+
# @return the created object, or nil if the given hash is nil
|
|
44
|
+
def create(hash)
|
|
45
|
+
return nil if hash.nil?
|
|
46
|
+
|
|
47
|
+
if @fields_to_map.nil? || @fields_to_map.empty?
|
|
48
|
+
fields = @kodi_fields
|
|
49
|
+
return nil if @kodi_fields.none? { |it| !hash[it.to_s.gsub('_', '')].nil? }
|
|
50
|
+
else
|
|
51
|
+
fields = @fields_to_map
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
mapping = @type_mapping.nil? ? lazy_type_mapping : @type_mapping
|
|
55
|
+
args = fields.map do |it|
|
|
56
|
+
field = it.to_s.gsub('_', '')
|
|
57
|
+
Creatable.extract_field_from_hash(field, hash, mapping)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
new(*args)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# takes a hash and a list of strings and an optional mapping and creates a new array with the created objects
|
|
64
|
+
# of the hash and fields. If no mapping is provided, the value of this field is returned, otherwise the mapping is
|
|
65
|
+
# used
|
|
66
|
+
# @param hash [Hash] the given hash
|
|
67
|
+
# @param fields [Array<String>] the fields to extract
|
|
68
|
+
# @param mapping [Hash<String, CreateMap>] optional mapping if a field contains a complex type
|
|
69
|
+
# @return [Array] an array containing the values of hash[field] in the given field order
|
|
70
|
+
def self.hash_to_arr(hash, fields, mapping = {})
|
|
71
|
+
return nil if hash.nil?
|
|
72
|
+
|
|
73
|
+
fields.map do |it|
|
|
74
|
+
field = it.to_s.gsub('_', '')
|
|
75
|
+
extract_field_from_hash(field, hash, mapping)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# map to self.hash_to_arr. The mapping is taken from #type_mapping
|
|
80
|
+
def hash_to_arr(hash, fields)
|
|
81
|
+
Creatable.hash_to_arr(hash, fields, @type_mapping.nil? ? {} : @type_mapping)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# extracts the given field from the given hash and optionally applies mapping if given
|
|
85
|
+
# @param field [String] the field name
|
|
86
|
+
# @param hash [Hash] the hash where to extract the field from
|
|
87
|
+
# @param mapping [Hash<String, CreateMap>] optional mapping for complex types
|
|
88
|
+
# @return the extracted object or nil, if the hash is empty, or [] if the expected value was a list and was nil
|
|
89
|
+
def self.extract_field_from_hash(field, hash, mapping)
|
|
90
|
+
map = mapping[field]
|
|
91
|
+
return nil if hash[field].nil? && map.nil?
|
|
92
|
+
|
|
93
|
+
return hash[field] if map.nil?
|
|
94
|
+
|
|
95
|
+
return map.type.create_list(hash[field]) if map.is_list
|
|
96
|
+
|
|
97
|
+
map.type.create(hash[field])
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def attr_accessor(*args)
|
|
101
|
+
attr_reader(*args)
|
|
102
|
+
attr_writer(*args)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def attr_reader(*args)
|
|
106
|
+
@kodi_fields = args.map { |it| it.to_s.gsub('_', '') }
|
|
107
|
+
|
|
108
|
+
args.each do |it|
|
|
109
|
+
inst_variable_name = "@#{it}".to_sym
|
|
110
|
+
define_method it do
|
|
111
|
+
instance_variable_get(inst_variable_name)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def attr_writer(*args)
|
|
117
|
+
args.each do |it|
|
|
118
|
+
inst_variable_name = "@#{it}".to_sym
|
|
119
|
+
define_method "#{it}=" do |new_value|
|
|
120
|
+
instance_variable_set(inst_variable_name, new_value)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# mapping class with the type and if it is a list field or not
|
|
126
|
+
class CreateMap
|
|
127
|
+
|
|
128
|
+
attr_reader :type, :is_list
|
|
129
|
+
|
|
130
|
+
def initialize(type, is_list = false)
|
|
131
|
+
@type = type
|
|
132
|
+
@is_list = is_list
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
module Extensions
|
|
5
|
+
# offers iterable methods
|
|
6
|
+
module Iterable
|
|
7
|
+
|
|
8
|
+
# @return [Array<String>] returns all constant values if sorted order
|
|
9
|
+
def all_properties
|
|
10
|
+
constants.map { |it| const_get(it) }.sort!
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
# represents an error response
|
|
5
|
+
class KodiError
|
|
6
|
+
include Extensions::Comparable
|
|
7
|
+
attr_reader :code, :message
|
|
8
|
+
|
|
9
|
+
def initialize(hash)
|
|
10
|
+
@code = hash['code']
|
|
11
|
+
@message = hash['message']
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
|
|
5
|
+
# the client that stores
|
|
6
|
+
class KodiMethod
|
|
7
|
+
|
|
8
|
+
def apply_options(options)
|
|
9
|
+
@endpoint_url = "#{options.tls ? 'https://' : 'http://'}#{options.ip}:#{options.port}/jsonrpc"
|
|
10
|
+
@options = options
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def invoke_api(request)
|
|
14
|
+
h = request.instance_variables.each_with_object({}) do |var, hash|
|
|
15
|
+
hash[var.to_s.delete('@')] = request.instance_variable_get(var)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
@http_client ||= build_client
|
|
19
|
+
response = @http_client.post(@endpoint_url, json: h).to_s
|
|
20
|
+
JSON.parse(response)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def build_client
|
|
24
|
+
client = HTTP.headers(Content_Type: 'application/json')
|
|
25
|
+
if !@options.username.nil? && !@options.password.nil?
|
|
26
|
+
client = client.basic_auth({ user: @options.username, pass: @options.password })
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
client
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private :build_client
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
# represents a kodi requests
|
|
5
|
+
class KodiRequest
|
|
6
|
+
|
|
7
|
+
attr_accessor :id, :jsonrpc, :method, :params
|
|
8
|
+
|
|
9
|
+
def initialize(kodi_id, method, params = {}, jsonrpc = '2.0')
|
|
10
|
+
@id = kodi_id
|
|
11
|
+
@jsonrpc = jsonrpc
|
|
12
|
+
@method = method
|
|
13
|
+
@params = params
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
# represents a kodi response
|
|
5
|
+
class KodiResponse
|
|
6
|
+
include Extensions::Comparable
|
|
7
|
+
|
|
8
|
+
attr_reader :id, :jsonrpc, :result, :error
|
|
9
|
+
|
|
10
|
+
def initialize(hash)
|
|
11
|
+
@id = hash['id']
|
|
12
|
+
@jsonrpc = hash['jsonrpc']
|
|
13
|
+
@result = hash['result']
|
|
14
|
+
@error = KodiError.new(hash['error']) unless hash['error'].nil?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def error?
|
|
18
|
+
!@error.nil?
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module KodiClient
|
|
4
|
-
module
|
|
4
|
+
module Methods
|
|
5
5
|
# contains all Kodi Application methods
|
|
6
|
-
class Addons <
|
|
6
|
+
class Addons < KodiMethod
|
|
7
7
|
|
|
8
8
|
EXECUTE_ADDON = 'Addons.ExecuteAddon'
|
|
9
9
|
GET_ADDON_DETAILS = 'Addons.GetAddonDetails'
|
|
@@ -24,7 +24,7 @@ module KodiClient
|
|
|
24
24
|
'installed' => installed.nil? || !installed ? 'all' : 'installed'
|
|
25
25
|
})
|
|
26
26
|
json = invoke_api(request)
|
|
27
|
-
result = Types::Addons::
|
|
27
|
+
result = Types::Addons::GetAddonsReturned.create(json['result'])
|
|
28
28
|
json['result'] = result
|
|
29
29
|
KodiResponse.new(json)
|
|
30
30
|
end
|
|
@@ -34,7 +34,7 @@ module KodiClient
|
|
|
34
34
|
'properties' => properties })
|
|
35
35
|
json = invoke_api(request)
|
|
36
36
|
|
|
37
|
-
result = Types::Addons::
|
|
37
|
+
result = Types::Addons::GetAddonReturned.create(json['result'])
|
|
38
38
|
json['result'] = result
|
|
39
39
|
KodiResponse.new(json)
|
|
40
40
|
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module KodiClient
|
|
4
|
-
module
|
|
4
|
+
module Methods
|
|
5
5
|
# contains all Kodi Application methods
|
|
6
|
-
class AudioLibrary <
|
|
6
|
+
class AudioLibrary < KodiMethod
|
|
7
7
|
|
|
8
8
|
CLEAN = 'AudioLibrary.Clean'
|
|
9
9
|
EXPORT = 'AudioLibrary.Export'
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module KodiClient
|
|
4
|
-
module
|
|
4
|
+
module Methods
|
|
5
5
|
# contains all Kodi Application methods
|
|
6
|
-
class Favourites <
|
|
6
|
+
class Favourites < KodiMethod
|
|
7
7
|
|
|
8
8
|
ADD_FAVOURITE = 'Favourites.AddFavourite'
|
|
9
9
|
GET_FAVOURITES = 'Favourites.GetFavourites'
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module KodiClient
|
|
4
|
-
module
|
|
4
|
+
module Methods
|
|
5
5
|
# contains all Kodi Application methods
|
|
6
|
-
class Files <
|
|
6
|
+
class Files < KodiMethod
|
|
7
7
|
|
|
8
8
|
GET_DIRECTORY = 'Files.GetDirectory'
|
|
9
9
|
GET_FILE_DETAILS = 'Files.GetFileDetails'
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module KodiClient
|
|
4
|
-
module
|
|
4
|
+
module Methods
|
|
5
5
|
# contains all Kodi Application methods
|
|
6
|
-
class Profiles <
|
|
6
|
+
class Profiles < KodiMethod
|
|
7
7
|
|
|
8
8
|
GET_CURRENT_PROFILE = 'Profiles.GetCurrentProfile'
|
|
9
9
|
GET_PROFILES = 'Profiles.GetProfiles'
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module KodiClient
|
|
4
|
-
module
|
|
4
|
+
module Methods
|
|
5
5
|
# contains all Kodi System methods
|
|
6
|
-
class System <
|
|
6
|
+
class System < KodiMethod
|
|
7
7
|
|
|
8
8
|
EJECT_OPTICAL_DRIVE = 'System.EjectOpticalDrive'
|
|
9
9
|
GET_PROPERTIES = 'System.GetProperties'
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
module Types
|
|
5
|
+
module Addons
|
|
6
|
+
# Addon.Content https://kodi.wiki/view/JSON-RPC_API/v12#Addon.Content
|
|
7
|
+
module AddonContent
|
|
8
|
+
extend Extensions::Iterable
|
|
9
|
+
|
|
10
|
+
UNKNOWN = 'unknown'
|
|
11
|
+
AUDIO = 'audio'
|
|
12
|
+
EXECUTABLE = 'executable'
|
|
13
|
+
IMAGE = 'image'
|
|
14
|
+
VIDEO = 'video'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
module Types
|
|
5
|
+
module Addons
|
|
6
|
+
# Addon.Details.dependencies https://kodi.wiki/view/JSON-RPC_API/v12#Addon.Details
|
|
7
|
+
class AddonDependency
|
|
8
|
+
include Extensions::Comparable
|
|
9
|
+
extend Extensions::Creatable
|
|
10
|
+
|
|
11
|
+
attr_reader :addon_id, :optional, :version
|
|
12
|
+
|
|
13
|
+
def initialize(addon_id, optional, version)
|
|
14
|
+
@addon_id = addon_id
|
|
15
|
+
@optional = optional
|
|
16
|
+
@version = version
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
module Types
|
|
5
|
+
module Addons
|
|
6
|
+
# represents addon details
|
|
7
|
+
class AddonDetails
|
|
8
|
+
include Extensions::Comparable
|
|
9
|
+
include Items::ItemDetailsBase
|
|
10
|
+
extend Extensions::Creatable
|
|
11
|
+
|
|
12
|
+
attr_reader :addon_id, :author, :broken, :dependencies, :description, :disclaimer, :enabled, :extra_info,
|
|
13
|
+
:fan_art, :installed, :name, :path, :rating, :summary, :thumbnail, :type, :version
|
|
14
|
+
|
|
15
|
+
fields_to_map %w[addon_id author broken dependencies description disclaimer enabled extra_info fan_art
|
|
16
|
+
installed name path rating summary thumbnail type version label]
|
|
17
|
+
|
|
18
|
+
type_mapping ['dependencies', AddonDependency, true], ['extrainfo', AddonExtraInfo, true]
|
|
19
|
+
|
|
20
|
+
def initialize(addon_id, author, broken, dependencies, description, disclaimer, enabled, extra_info,
|
|
21
|
+
fan_art, installed, name, path, rating, summary, thumbnail, type, version, label)
|
|
22
|
+
@addon_id = addon_id
|
|
23
|
+
@author = author
|
|
24
|
+
@broken = broken
|
|
25
|
+
@dependencies = dependencies
|
|
26
|
+
@description = description
|
|
27
|
+
@disclaimer = disclaimer
|
|
28
|
+
@enabled = enabled
|
|
29
|
+
@extra_info = extra_info
|
|
30
|
+
@fan_art = fan_art
|
|
31
|
+
@installed = installed
|
|
32
|
+
@name = name
|
|
33
|
+
@path = path
|
|
34
|
+
@rating = rating
|
|
35
|
+
@summary = summary
|
|
36
|
+
@thumbnail = thumbnail
|
|
37
|
+
@type = type
|
|
38
|
+
@version = version
|
|
39
|
+
item_details_base(label)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
module Types
|
|
5
|
+
module Addons
|
|
6
|
+
# Addon.Details.extrainfo https://kodi.wiki/view/JSON-RPC_API/v12#Addon.Details
|
|
7
|
+
class AddonExtraInfo
|
|
8
|
+
include Extensions::Comparable
|
|
9
|
+
extend Extensions::Creatable
|
|
10
|
+
|
|
11
|
+
attr_reader :key, :value
|
|
12
|
+
|
|
13
|
+
def initialize(key, value)
|
|
14
|
+
@key = key
|
|
15
|
+
@value = value
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KodiClient
|
|
4
|
+
module Types
|
|
5
|
+
module Addons
|
|
6
|
+
# Addon.Fields https://kodi.wiki/view/JSON-RPC_API/v12#Addon.Content
|
|
7
|
+
module AddonFields
|
|
8
|
+
extend Extensions::Iterable
|
|
9
|
+
|
|
10
|
+
AUTHOR = 'author'
|
|
11
|
+
BROKEN = 'broken'
|
|
12
|
+
DEPENDENCIES = 'dependencies'
|
|
13
|
+
DESCRIPTION = 'description'
|
|
14
|
+
DISCLAIMER = 'disclaimer'
|
|
15
|
+
ENABLED = 'enabled'
|
|
16
|
+
EXTRAINFO = 'extrainfo'
|
|
17
|
+
FANART = 'fanart'
|
|
18
|
+
INSTALLED = 'installed'
|
|
19
|
+
NAME = 'name'
|
|
20
|
+
PATH = 'path'
|
|
21
|
+
RATING = 'rating'
|
|
22
|
+
SUMMARY = 'summary'
|
|
23
|
+
THUMBNAIL = 'thumbnail'
|
|
24
|
+
VERSION = 'version'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|