conversant 1.0.16

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.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.env.example +39 -0
  3. data/.gitignore +52 -0
  4. data/.gitlab-ci.yml +108 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +16 -0
  7. data/.yardopts +7 -0
  8. data/CHANGELOG.md +487 -0
  9. data/Gemfile +12 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +860 -0
  12. data/RELEASE.md +726 -0
  13. data/Rakefile +21 -0
  14. data/conversant.gemspec +49 -0
  15. data/examples/inheritance_integration.rb +348 -0
  16. data/examples/rails_initializer.rb +69 -0
  17. data/lib/conversant/configuration.rb +132 -0
  18. data/lib/conversant/v3/base.rb +47 -0
  19. data/lib/conversant/v3/http_client.rb +456 -0
  20. data/lib/conversant/v3/mixins/authentication.rb +221 -0
  21. data/lib/conversant/v3/services/authorization.rb +194 -0
  22. data/lib/conversant/v3/services/cdn/analytics.rb +483 -0
  23. data/lib/conversant/v3/services/cdn/audit.rb +71 -0
  24. data/lib/conversant/v3/services/cdn/business.rb +122 -0
  25. data/lib/conversant/v3/services/cdn/certificate.rb +180 -0
  26. data/lib/conversant/v3/services/cdn/dashboard.rb +109 -0
  27. data/lib/conversant/v3/services/cdn/domain.rb +223 -0
  28. data/lib/conversant/v3/services/cdn/monitoring.rb +65 -0
  29. data/lib/conversant/v3/services/cdn/partner/analytics.rb +233 -0
  30. data/lib/conversant/v3/services/cdn/partner.rb +60 -0
  31. data/lib/conversant/v3/services/cdn.rb +221 -0
  32. data/lib/conversant/v3/services/lms/dashboard.rb +99 -0
  33. data/lib/conversant/v3/services/lms/domain.rb +108 -0
  34. data/lib/conversant/v3/services/lms/job.rb +211 -0
  35. data/lib/conversant/v3/services/lms/partner/analytics.rb +266 -0
  36. data/lib/conversant/v3/services/lms/partner/business.rb +151 -0
  37. data/lib/conversant/v3/services/lms/partner/report.rb +170 -0
  38. data/lib/conversant/v3/services/lms/partner.rb +58 -0
  39. data/lib/conversant/v3/services/lms/preset.rb +57 -0
  40. data/lib/conversant/v3/services/lms.rb +173 -0
  41. data/lib/conversant/v3/services/oss/partner/analytics.rb +105 -0
  42. data/lib/conversant/v3/services/oss/partner.rb +48 -0
  43. data/lib/conversant/v3/services/oss.rb +128 -0
  44. data/lib/conversant/v3/services/portal/dashboard.rb +114 -0
  45. data/lib/conversant/v3/services/portal.rb +219 -0
  46. data/lib/conversant/v3/services/vms/analytics.rb +114 -0
  47. data/lib/conversant/v3/services/vms/business.rb +190 -0
  48. data/lib/conversant/v3/services/vms/partner/analytics.rb +133 -0
  49. data/lib/conversant/v3/services/vms/partner/business.rb +90 -0
  50. data/lib/conversant/v3/services/vms/partner.rb +57 -0
  51. data/lib/conversant/v3/services/vms/transcoding.rb +184 -0
  52. data/lib/conversant/v3/services/vms.rb +166 -0
  53. data/lib/conversant/v3.rb +36 -0
  54. data/lib/conversant/version.rb +5 -0
  55. data/lib/conversant.rb +108 -0
  56. data/publish.sh +107 -0
  57. data/sig/conversant/v3/services/authorization.rbs +34 -0
  58. data/sig/conversant/v3/services/cdn.rbs +123 -0
  59. data/sig/conversant/v3/services/lms.rbs +80 -0
  60. data/sig/conversant/v3/services/portal.rbs +22 -0
  61. data/sig/conversant/v3/services/vms.rbs +64 -0
  62. data/sig/conversant/v3.rbs +85 -0
  63. data/sig/conversant.rbs +37 -0
  64. metadata +267 -0
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Conversant
4
+ module V3
5
+ module Services
6
+ class VMS
7
+ class Partner
8
+ # VMS Business analytics for partner-level business reporting
9
+ #
10
+ # Provides business-focused analytics methods that aggregate transcoding
11
+ # data for VOD (Video on Demand) billing and capacity planning.
12
+ #
13
+ # @since 1.0.16
14
+ class Business
15
+ # @return [Conversant::V3::Services::VMS::Partner::Analytics] the parent analytics instance
16
+ attr_reader :parent
17
+
18
+ # Initialize partner VMS business service
19
+ #
20
+ # @param parent [Conversant::V3::Services::VMS::Partner::Analytics] the parent analytics instance
21
+ def initialize(parent)
22
+ @parent = parent
23
+ end
24
+
25
+ # Fetches transcoding business analytics with codec breakdown
26
+ #
27
+ # Aggregates VOD transcoding data including transmuxing and transcoding
28
+ # across different resolutions (SD, HD, UHD) and codecs (H264, H265).
29
+ #
30
+ # @param args [Hash] Parameters for the query
31
+ # @option args [Time, String] :startTime start time for the report (defaults to beginning of current month)
32
+ # @option args [String, Integer] :type customer type filter (defaults to 2)
33
+ #
34
+ # @return [Hash] Transcoding business data with breakdown by codec and resolution. Hash contains:
35
+ # - :vms_transcoding [Float] total transcoding duration
36
+ # - :vms_transmuxing [Float] transmuxing duration
37
+ # - :vms_transcoding_sd [Float] SD transcoding duration
38
+ # - :vms_transcoding_hd [Float] HD transcoding duration
39
+ # - :vms_transcoding_uhd [Float] UHD transcoding duration
40
+ #
41
+ # @example Get VOD transcoding business metrics
42
+ # vms = Conversant::V3.vms(12345)
43
+ # business = vms.partner.analytics.business
44
+ # metrics = business.transcoding(startTime: Time.now.beginning_of_month)
45
+ # puts "Total transcoding: #{metrics[:vms_transcoding]} minutes"
46
+ # puts "SD: #{metrics[:vms_transcoding_sd]}, HD: #{metrics[:vms_transcoding_hd]}, UHD: #{metrics[:vms_transcoding_uhd]}"
47
+ #
48
+ # @since 1.0.16
49
+ def transcoding(**args)
50
+ transcoding = {
51
+ vms_transcoding: 0,
52
+ vms_transmuxing: 0,
53
+ vms_transcoding_sd: 0,
54
+ vms_transcoding_hd: 0,
55
+ vms_transcoding_uhd: 0
56
+ }
57
+
58
+ data = @parent.duration_of_vod(**args).first
59
+ return transcoding if data.nil?
60
+
61
+ name = data.keys.first
62
+
63
+ if data[name].present?
64
+ data[name].each do |item|
65
+ transcoding[:vms_transmuxing] += item['transmux'].to_f
66
+ transcoding[:vms_transcoding_sd] += item['h264SdTranscoding'].to_f + item['h265SdTranscoding'].to_f
67
+ transcoding[:vms_transcoding_hd] += item['h264HdTranscoding'].to_f + item['h265HdTranscoding'].to_f
68
+ transcoding[:vms_transcoding_uhd] += item['h264UhdTranscoding'].to_f + item['h265UhdTranscoding'].to_f
69
+ end
70
+ end
71
+
72
+ transcoding[:vms_transcoding] =
73
+ transcoding[:vms_transcoding_sd] + transcoding[:vms_transcoding_hd] + transcoding[:vms_transcoding_uhd]
74
+ transcoding
75
+ rescue StandardError => e
76
+ logger.error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
77
+ transcoding
78
+ end
79
+
80
+ private
81
+
82
+ def logger
83
+ @parent.send(:logger)
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Conversant
4
+ module V3
5
+ module Services
6
+ class VMS
7
+ # Partner service for VMS partner-level operations
8
+ #
9
+ # Provides access to partner-level analytics for Video Management System
10
+ # that aggregate data across multiple customer accounts.
11
+ #
12
+ # @example Access partner analytics
13
+ # vms = Conversant::V3.vms(12345)
14
+ #
15
+ # # Partner-level VMS analytics
16
+ # transcoding = vms.partner.analytics.transcoding({
17
+ # startTime: "2025-01-01T00:00:00Z",
18
+ # endTime: "2025-01-31T23:59:59Z"
19
+ # })
20
+ #
21
+ # @since 1.0.12
22
+ class Partner
23
+ # @return [VMS] the parent VMS service instance
24
+ attr_reader :parent
25
+
26
+ # Initialize partner service
27
+ #
28
+ # @param parent [VMS] the parent VMS service instance
29
+ def initialize(parent)
30
+ @parent = parent
31
+ end
32
+
33
+ # Get partner analytics service instance
34
+ #
35
+ # Provides partner-level analytics for VMS services including transcoding
36
+ # duration, volume, and processing metrics across multiple customers.
37
+ #
38
+ # @return [Analytics] VMS partner analytics service
39
+ # @since 1.0.12
40
+ def analytics
41
+ @analytics ||= Analytics.new(@parent)
42
+ end
43
+
44
+ private
45
+
46
+ def logger
47
+ @parent.send(:logger)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ # Load nested analytics class after Partner is defined
56
+ require_relative 'partner/analytics'
57
+ require_relative 'partner/business'
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Conversant
4
+ module V3
5
+ module Services
6
+ class VMS
7
+ # Video transcoding service for job and preset management
8
+ #
9
+ # Provides comprehensive job and preset management functionality for
10
+ # video transcoding operations including:
11
+ # - Transcoding job listing and filtering
12
+ # - Preset configuration management
13
+ # - Job status tracking
14
+ #
15
+ # @example Manage transcoding jobs
16
+ # vms = Conversant::V3.vms(12345)
17
+ #
18
+ # # Get recent transcoding jobs
19
+ # jobs = vms.transcoding.jobs(page_size: 50, job_status: 2)
20
+ #
21
+ # jobs.each do |job|
22
+ # puts "Job #{job['id']}: #{job['file_name']} - #{job['status']}"
23
+ # end
24
+ #
25
+ # # Get available presets
26
+ # presets = vms.transcoding.presets
27
+ #
28
+ # @since 1.0.0
29
+ class Transcoding
30
+ # @return [VMS] the parent VMS service instance
31
+ attr_reader :parent
32
+
33
+ # Initialize VOD transcoding service
34
+ #
35
+ # @param parent [VMS] the parent VMS service instance
36
+ def initialize(parent)
37
+ @parent = parent
38
+ end
39
+
40
+ # Get list of transcoding jobs
41
+ #
42
+ # Retrieves a paginated list of video transcoding jobs with filtering options.
43
+ # Returns detailed information about each job including status, file name,
44
+ # transcoding configurations, and timestamps.
45
+ #
46
+ # @param payload [Hash] query parameters for filtering and pagination
47
+ # @option payload [Integer] :page_number page number (default: 1)
48
+ # @option payload [Integer] :page_size number of results per page (default: 20)
49
+ # @option payload [Integer] :job_status filter by job status (-1 for all)
50
+ # @option payload [Integer] :source_type filter by source type (-1 for all)
51
+ # @option payload [Integer] :output_format filter by output format (-1 for all)
52
+ # @option payload [Integer] :protection_type filter by protection type (-1 for all)
53
+ # @option payload [String] :file_name filter by file name
54
+ # @option payload [String] :period time period filter (e.g., '0_30' for last 30 days)
55
+ # @option payload [Integer] :job_type job type filter (default: 1)
56
+ #
57
+ # @return [Array<Hash>] array of transcoding job records, or empty array on error
58
+ #
59
+ # @example Get recent transcoding jobs
60
+ # jobs = vms.vod_transcoding.jobs(page_size: 50)
61
+ # jobs.each { |job| puts "#{job['file_name']}: #{job['status']}" }
62
+ #
63
+ # @example Filter by status
64
+ # active_jobs = vms.vod_transcoding.jobs(job_status: 2, page_size: 100)
65
+ #
66
+ # @since 1.0.0
67
+ def jobs(payload = {})
68
+ default_payload = {
69
+ sEcho: 1,
70
+ iColumns: 9,
71
+ sColumns: nil,
72
+ iDisplayStart: 0,
73
+ iDisplayLength: 20,
74
+ mDataProp_0: 'id',
75
+ mDataProp_1: 'file_name',
76
+ mDataProp_2: 'transcoding_configs',
77
+ mDataProp_3: 'created',
78
+ mDataProp_4: 'source_type',
79
+ mDataProp_5: 'ended',
80
+ mDataProp_6: 'transcoding_configs',
81
+ mDataProp_7: 'status',
82
+ mDataProp_8: 'id',
83
+ iSortingCols: '0',
84
+ bSortable_0: 'false',
85
+ bSortable_1: 'true',
86
+ bSortable_2: 'false',
87
+ bSortable_3: 'true',
88
+ bSortable_4: 'false',
89
+ bSortable_5: 'true',
90
+ bSortable_6: 'false',
91
+ bSortable_7: 'false',
92
+ bSortable_8: 'false',
93
+ page_number: 1,
94
+ page_size: 20,
95
+ sort_field: nil,
96
+ sort_type: nil,
97
+ job_status: -1,
98
+ source_type: -1,
99
+ output_format: -1,
100
+ protection_type: -1,
101
+ file_name: nil,
102
+ period: '0_30',
103
+ job_type: 1,
104
+ _: (Time.now.to_f * 1000).to_i
105
+ }
106
+
107
+ merged_payload = default_payload.merge(payload)
108
+ response = @parent.send(:call, 'GET', "/v2/jobs?#{merged_payload.to_query}")
109
+ return [] if response.nil?
110
+
111
+ JSON.parse(response)&.[]("list") || []
112
+ rescue StandardError => e
113
+ logger.error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
114
+ []
115
+ end
116
+
117
+ # Get list of transcoding presets
118
+ #
119
+ # Retrieves a paginated list of transcoding preset configurations.
120
+ # Presets define encoding parameters such as resolution, bitrate,
121
+ # codec settings, and output formats.
122
+ #
123
+ # @param payload [Hash] query parameters for pagination
124
+ # @option payload [Integer] :page_number page number (default: 1)
125
+ # @option payload [Integer] :page_size number of results per page (default: 20)
126
+ #
127
+ # @return [Array<Hash>] array of transcoding preset configurations, or empty array on error
128
+ #
129
+ # @example Get available presets
130
+ # presets = vms.vod_transcoding.presets
131
+ # presets.each do |preset|
132
+ # puts "#{preset['name']}: #{preset['description']}"
133
+ # end
134
+ #
135
+ # @example Get first page with custom size
136
+ # presets = vms.vod_transcoding.presets(page_number: 1, page_size: 50)
137
+ #
138
+ # @since 1.0.0
139
+ def presets(payload = {})
140
+ default_payload = {
141
+ sEcho: 1,
142
+ iColumns: 5,
143
+ sColumns: nil,
144
+ iDisplayStart: 0,
145
+ iDisplayLength: 20,
146
+ mDataProp_0: 'id',
147
+ mDataProp_1: 'name',
148
+ mDataProp_2: 'id',
149
+ mDataProp_3: 'description',
150
+ mDataProp_4: 'id',
151
+ iSortingCols: '0',
152
+ bSortable_0: 'false',
153
+ bSortable_1: 'false',
154
+ bSortable_2: 'false',
155
+ bSortable_3: 'false',
156
+ bSortable_4: 'false',
157
+ page_number: 1,
158
+ page_size: 20,
159
+ _: (Time.now.to_f * 1000).to_i
160
+ }
161
+
162
+ merged_payload = default_payload.merge(payload)
163
+ response = @parent.send(:call, 'GET', "/v2/osp/presets?#{merged_payload.to_query}")
164
+ return [] if response.nil?
165
+
166
+ JSON.parse(response)&.[]("list") || []
167
+ rescue StandardError => e
168
+ logger.error "#{@parent.send(:identifier)}.METHOD:#{__method__}.EXCEPTION:#{e.message}"
169
+ []
170
+ end
171
+
172
+ private
173
+
174
+ # Get logger instance from parent
175
+ #
176
+ # @return [Logger] logger instance
177
+ def logger
178
+ @parent.send(:logger)
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'authorization'
4
+
5
+ module Conversant
6
+ module V3
7
+ module Services
8
+ # Video Management System (VMS) service for video processing and management
9
+ #
10
+ # Provides comprehensive functionality for video operations including:
11
+ # - VOD (Video on Demand) transcoding management
12
+ # - Analytics for video metrics and usage
13
+ # - Business metrics for billing and reporting
14
+ #
15
+ # @example Basic usage
16
+ # vms = Conversant::V3.vms(12345)
17
+ #
18
+ # # Get transcoding jobs
19
+ # jobs = vms.transcoding.jobs(page_number: 1)
20
+ #
21
+ # # Get analytics
22
+ # volume = vms.analytics.volume(startTime: '2025-01-01')
23
+ #
24
+ # @since 1.0.0
25
+ class VMS < ::Conversant::V3::Base
26
+ include Authorization
27
+
28
+ # Get transcoding service instance
29
+ #
30
+ # @return [Transcoding] transcoding service for job management
31
+ # @since 1.0.0
32
+ def transcoding
33
+ @transcoding ||= Transcoding.new(self)
34
+ end
35
+
36
+ # Get analytics service instance
37
+ #
38
+ # @return [Analytics] analytics service for video metrics
39
+ # @since 1.0.0
40
+ def analytics
41
+ @analytics ||= Analytics.new(self)
42
+ end
43
+
44
+ # Get business metrics service instance
45
+ #
46
+ # @return [Business] business service for billing metrics
47
+ # @since 1.0.0
48
+ def business
49
+ @business ||= Business.new(self)
50
+ end
51
+
52
+ # Get partner service instance
53
+ #
54
+ # Provides access to partner-level analytics for Video Management System
55
+ # that aggregate data across multiple customer accounts.
56
+ #
57
+ # @return [Partner] partner service for VMS analytics
58
+ # @since 1.0.12
59
+ #
60
+ # @example Access partner analytics
61
+ # vms = Conversant::V3.vms(12345)
62
+ # transcoding = vms.partner.analytics.transcoding(payload)
63
+ def partner
64
+ @partner ||= Partner.new(self)
65
+ end
66
+
67
+ # @deprecated Use {#partner} instead
68
+ # Get partner analytics service instance (deprecated)
69
+ #
70
+ # @return [VMS::Partner::Analytics] partner analytics for VMS reporting
71
+ # @since 1.0.8
72
+ # @deprecated Use `vms.partner.analytics` instead of `vms.partner_analytics`
73
+ def partner_analytics
74
+ @partner_analytics ||= Partner::Analytics.new(self)
75
+ end
76
+
77
+ protected
78
+
79
+ def call(method, uri, payload = nil)
80
+ url = "#{configuration.private_vms_endpoint}#{uri}"
81
+
82
+ headers = authorized_headers
83
+
84
+ # Check for JSESSIONID in Cookie header
85
+ if headers['Cookie'].nil? || !headers['Cookie'].include?('JSESSIONID=')
86
+ logger.error "#{identifier}.METHOD:call.NO_JSESSIONID"
87
+ raise AuthenticationError, 'Missing JSESSIONID for VMS'
88
+ end
89
+
90
+ code, response = request(method, url, payload, headers)
91
+
92
+ if code >= 400
93
+ logger.error "#{identifier}.METHOD:call.HTTP_ERROR:#{code}"
94
+ raise ApiError, "VMS API error: #{code}"
95
+ end
96
+
97
+ response.body
98
+ end
99
+
100
+ private
101
+
102
+ def fetch_new_session
103
+ sessions = authenticate
104
+ return nil unless sessions && sessions[:session] && sessions[:sso_gw_session2]
105
+
106
+ timestamp = (Time.now.to_f * 1000).to_i
107
+ reporting_url = "#{configuration.private_vms_endpoint}/reporting/vms/federation/business/usage"
108
+ reporting_url += "?customerId=#{customer_id}&type=#{type || 2}&t=#{timestamp}"
109
+
110
+ logger.debug "#{identifier}.METHOD:authorize.REQUESTING_JSESSIONID"
111
+
112
+ response = RestClient.get(
113
+ reporting_url,
114
+ {
115
+ authority: URI.parse(configuration.private_vms_endpoint).hostname,
116
+ referer: portal_endpoint,
117
+ user_agent: configuration.default_ua,
118
+ cookies: {
119
+ 'SESSION': sessions[:session],
120
+ 'SSO_GW_SESSION2': sessions[:sso_gw_session2]
121
+ },
122
+ timeout: 30,
123
+ open_timeout: 30
124
+ }
125
+ )
126
+
127
+ if response.cookies['JSESSIONID']
128
+ jsessionid = response.cookies['JSESSIONID']
129
+ redis.set(session_cache_key, jsessionid, ex: configuration.cache_ttl)
130
+ logger.debug "#{identifier}.METHOD:authorize.JSESSIONID_OBTAINED"
131
+ jsessionid
132
+ else
133
+ logger.error "#{identifier}.METHOD:authorize.NO_JSESSIONID_IN_RESPONSE"
134
+ nil
135
+ end
136
+ rescue RestClient::Unauthorized, RestClient::Forbidden => e
137
+ logger.error "#{identifier}.METHOD:authorize.AUTH_ERROR:#{e.message}"
138
+ nil
139
+ rescue StandardError => e
140
+ logger.error "#{identifier}.METHOD:authorize.ERROR:#{e.message}"
141
+ nil
142
+ end
143
+
144
+ protected
145
+
146
+ def service_endpoint
147
+ configuration.private_vms_endpoint
148
+ end
149
+
150
+ def session_cookie_name
151
+ 'JSESSIONID'
152
+ end
153
+
154
+ def requires_session?
155
+ true
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+ # Load nested service classes after VMS is defined
163
+ require_relative 'vms/transcoding'
164
+ require_relative 'vms/analytics'
165
+ require_relative 'vms/business'
166
+ require_relative 'vms/partner'
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'v3/http_client'
4
+ require_relative 'v3/base'
5
+ require_relative 'v3/mixins/authentication'
6
+ require_relative 'v3/services/portal'
7
+ require_relative 'v3/services/cdn'
8
+ require_relative 'v3/services/lms'
9
+ require_relative 'v3/services/vms'
10
+ require_relative 'v3/services/oss'
11
+
12
+ module Conversant
13
+ module V3
14
+ class << self
15
+ def portal(customer_id, type = 2)
16
+ Services::Portal.new(customer_id, type)
17
+ end
18
+
19
+ def cdn(customer_id, type = 2)
20
+ Services::CDN.new(customer_id, type)
21
+ end
22
+
23
+ def lms(customer_id, type = 2)
24
+ Services::LMS.new(customer_id, type)
25
+ end
26
+
27
+ def vms(customer_id, type = 2)
28
+ Services::VMS.new(customer_id, type)
29
+ end
30
+
31
+ def oss(customer_id, type = 2)
32
+ Services::OSS.new(customer_id, type)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Conversant
4
+ VERSION = '1.0.16'
5
+ end
data/lib/conversant.rb ADDED
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require 'json'
5
+ require 'redis'
6
+ require 'cgi'
7
+ require 'logger'
8
+ require 'uri'
9
+ require 'ostruct'
10
+ require 'date'
11
+ require 'time'
12
+
13
+ require_relative 'conversant/version'
14
+ require_relative 'conversant/configuration'
15
+ require_relative 'conversant/v3'
16
+
17
+ # Conversant Ruby Gem
18
+ #
19
+ # A Ruby client library for interacting with Conversant/SwiftFederation CDN services.
20
+ # Provides clean interfaces for Portal, CDN, and LMS APIs with V3 authentication support.
21
+ #
22
+ # @example Basic usage with zero configuration
23
+ # # If ENV variables are already set, just use it:
24
+ # portal = Conversant::V3.portal(customer_id)
25
+ # cdn = Conversant::V3.cdn(customer_id)
26
+ # lms = Conversant::V3.lms(customer_id)
27
+ #
28
+ # @example Manual configuration
29
+ # Conversant.configure do |config|
30
+ # config.private_cdn_endpoint = 'https://cdn.example.com'
31
+ # config.private_lms_endpoint = 'https://lms.example.com'
32
+ # config.redis = Redis.new(url: ENV['REDIS_URL'])
33
+ # end
34
+ #
35
+ # @see https://gitlab.vnetwork.dev/gems/conversant
36
+ # @author Tho Nguyen
37
+ module Conversant
38
+ # Base error class for all Conversant errors
39
+ class Error < StandardError; end
40
+
41
+ # Raised when authentication fails
42
+ class AuthenticationError < Error; end
43
+
44
+ # Raised when API calls fail
45
+ class ApiError < Error; end
46
+
47
+ class << self
48
+ # @return [Configuration] the global configuration object
49
+ attr_accessor :configuration
50
+ end
51
+
52
+ # Configure the Conversant gem
53
+ #
54
+ # @yield [config] Configuration object
55
+ # @yieldparam config [Configuration] the configuration object
56
+ # @return [Configuration] the configuration object
57
+ #
58
+ # @example
59
+ # Conversant.configure do |config|
60
+ # config.cache_ttl = 3600
61
+ # config.debug_mode = true
62
+ # end
63
+ def self.configure
64
+ self.configuration ||= Configuration.new
65
+ yield(configuration) if block_given?
66
+ configuration
67
+ end
68
+
69
+ # Auto-configure from environment variables
70
+ #
71
+ # Automatically loads configuration from ENV variables and validates.
72
+ # Uses existing CONVERSANT environment variables as defaults.
73
+ #
74
+ # @return [Configuration] the configured object
75
+ # @raise [Error] if required configuration is missing
76
+ #
77
+ # @example
78
+ # Conversant.auto_configure!
79
+ def self.auto_configure!
80
+ self.configuration = Configuration.new
81
+
82
+ # Auto-detect and set Redis if available
83
+ if defined?($redis) && $redis
84
+ configuration.redis = $redis
85
+ elsif defined?(Redis) && ENV['REDIS_URL']
86
+ configuration.redis = Redis.new(url: ENV['REDIS_URL'])
87
+ elsif defined?(Redis)
88
+ configuration.redis = Redis.new
89
+ end
90
+
91
+ configuration.validate!
92
+ configuration
93
+ end
94
+
95
+ # Reset configuration to defaults
96
+ #
97
+ # @return [Configuration] new configuration object
98
+ def self.reset_configuration!
99
+ self.configuration = Configuration.new
100
+ end
101
+
102
+ # Check if gem is configured
103
+ #
104
+ # @return [Boolean] true if configured, false otherwise
105
+ def self.configured?
106
+ !configuration.nil?
107
+ end
108
+ end