open_trivia_db 1.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 77aa97e8f9ab56cb8ab2bc4a9bcf85282dc4b87e6fb480a9f6a0459b2417cf45
4
+ data.tar.gz: cb21d1ff8f997467f2ca084cbba5ed949ff5e4d4b5fefff7eb1253144fe48f56
5
+ SHA512:
6
+ metadata.gz: a09f7678ddf01d40f043feac3e3f6c9b07e822f4ed3fb09ecc157fca91b7fa97cdd2251d5ee85265a576753cdd36c739773547a304d6e86e77fb8f606345682b
7
+ data.tar.gz: d6d09c62480f9d4bbfcf6c1eafbe143f9b6f435d2a5f2d291b4a8d74b8a3f92deebcb84f8537b58193acdbf002f9f0a06b6e752ad54555840f57c9391a277a78
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'generate_answer_key'
4
+
5
+ #
6
+ # Generate a key with location of the correct answer based length of the category text
7
+ #
8
+ class CategoryTextKeyGenerator
9
+ include GenerateAnswerKey
10
+
11
+ #
12
+ # Encrypt answer_key
13
+ #
14
+ # @param [hash] question question information
15
+ #
16
+ # @return [hash] answer key
17
+ #
18
+ def self.update_answer_key(question)
19
+ correct_answer = question[:answer_key].to_s
20
+ location = question[:category].length % 10
21
+ answer_key = GenerateAnswerKey.get_random_key(location) +
22
+ correct_answer +
23
+ GenerateAnswerKey.get_random_key(9 - location)
24
+ question[:answer_key] = answer_key
25
+ end
26
+
27
+ #
28
+ # Decrypt answer key
29
+ #
30
+ # @param [hash] question
31
+ #
32
+ # @return [integer] index of the correct answer from the answer array
33
+ #
34
+ def self.decrypt_answer_key(question)
35
+ location = question[:category].length % 10
36
+ question[:answer_key][location].to_i
37
+ end
38
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Interface for generating a custom answer key
5
+ #
6
+ module GenerateAnswerKey
7
+
8
+ #
9
+ # Encrypt answer key
10
+ #
11
+ # @param [hash] question
12
+ #
13
+ def self.update_answer_key(question)
14
+ raise NoMethodError("generate method not implemented")
15
+ end
16
+
17
+ #
18
+ # Decrypt answer key.
19
+ #
20
+ # @param [hash] question
21
+ #
22
+ # @return [int] index of the correct answer
23
+ #
24
+ def self.decrypt_answer_key(question)
25
+ raise NoMethodError("decrypt method not implemented")
26
+ end
27
+ #
28
+ # Generate a random key of length 10 numbers
29
+ #
30
+ # @return [string] random key
31
+ #
32
+ def self.get_random_key(n = 10)
33
+ return '' if n.zero?
34
+ min = 10**n
35
+ max = 10**(n+1)-1
36
+ rand(min..max).to_s[0..n-1]
37
+ end
38
+
39
+ #
40
+ # Generate a random word
41
+ #
42
+ # @param [int] n specify length of word
43
+ #
44
+ # @return [string] generated word
45
+ #
46
+ def self.get_random_word(n = 7)
47
+ letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
48
+ word = ''
49
+ n.times do
50
+ word += letters[rand(52)]
51
+ end
52
+ word
53
+ end
54
+
55
+ #
56
+ # Generate a random phrase
57
+ #
58
+ # @param [integer] n number of words
59
+ #
60
+ # @return [string] phrase
61
+ #
62
+ def self.get_random_phrase(n = 4)
63
+ phrase = ''
64
+ n.times do
65
+ phrase += (phrase.length == 0 ? '': ' ') + self.get_random_word(rand(7)+3)
66
+ end
67
+ phrase
68
+ end
69
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'generate_answer_key'
4
+
5
+ #
6
+ # Generate a key with location of the correct answer based on the first two digits
7
+ #
8
+ class LeadingDigitsKeyGenerator
9
+ include GenerateAnswerKey
10
+
11
+ #
12
+ # Encrypt answer_key
13
+ #
14
+ # @param [hash] question question information
15
+ #
16
+ # @return [hash] answer key
17
+ #
18
+ def self.update_answer_key(question)
19
+ correct_answer = question[:answer_key].to_s
20
+ key = GenerateAnswerKey.get_random_key
21
+ location = key[0..1].to_i % 8
22
+ answer_key = key[0..(location + 1)] + correct_answer + key[location + 3..9]
23
+ question[:answer_key] = answer_key
24
+ end
25
+
26
+ #
27
+ # Decrypt answer key
28
+ #
29
+ # @param [hash] question
30
+ #
31
+ # @return [integer] index of the correct answer from the answer array
32
+ #
33
+ def self.decrypt_answer_key(question)
34
+ location = question[:answer_key].to_s[0..1].to_i % 8
35
+ question[:answer_key][location + 2].to_i
36
+ end
37
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+
6
+ require_relative 'leading_digits_key_generator'
7
+
8
+ #
9
+ # Retrieve questions from {OpenTrivia DB}[https://opentdb.com/] with an encrypted
10
+ # answer key
11
+ #
12
+ class OpenTriviaDB
13
+ # @return [class] Generator that implements the GenerateAnswerKey interface
14
+ attr_accessor :generator
15
+
16
+ # @return [string] url of the service; defaults to {https://opentdb.com/api.php}[https://opentdb.com/api.php]
17
+ attr_accessor :url
18
+
19
+ #
20
+ #
21
+ #
22
+ def initialize
23
+ @url = 'https://opentdb.com/api.php'
24
+ end
25
+
26
+ #
27
+ # Retrieve questions from OpenTrivia DB. See
28
+ # {Trivia API}[https://opentdb.com/api_config.php] for definition of parameters.
29
+ #
30
+ # @option params [hash] :params query parameters
31
+ #
32
+ # @return [hash] question list
33
+ #
34
+ def get(params = {})
35
+ # Ensure amount parameter passed
36
+ params = params.merge({ amount: 10 }, params)
37
+
38
+ uri = URI(@url)
39
+ uri.query = URI.encode_www_form(params)
40
+ res = Net::HTTP.get_response(uri)
41
+
42
+ out = {
43
+ response_code: 0,
44
+ response_message: 'OK',
45
+ params: params,
46
+ questions: {}
47
+ }
48
+
49
+ # rubocop:disable Style/ConditionalAssignment
50
+ case res.code.to_i
51
+ when 200
52
+ json = JSON.parse(res.body)
53
+ case json['response_code']
54
+ when 0
55
+ # Valid query
56
+ out = out.merge({
57
+ questions: process_questions(json['results'])
58
+ })
59
+ else
60
+ # Invalid, possibly parameters related
61
+ out = out.merge({
62
+ response_code: json['response_code'],
63
+ response_message: 'invalid query'
64
+ })
65
+ end
66
+ else
67
+ # Server error (ie 404, 503)
68
+ out = out.merge({
69
+ response_code: res.code.to_i,
70
+ response_message: res.message
71
+ })
72
+ end
73
+ # rubocop:enable Style/ConditionalAssignment
74
+ out
75
+ end
76
+
77
+ private
78
+
79
+ #
80
+ # Reformat questions and randomize answers
81
+ #
82
+ # @param [Array] list questions from the api
83
+ #
84
+ # @return [Array] reformated questions
85
+ #
86
+ def process_questions(list)
87
+ questions = []
88
+ list.each_with_index do |q, i|
89
+ question = {}
90
+ question[:id] = i + 1
91
+ question[:category] = q['category']
92
+ question[:difficulty] = q['difficulty']
93
+ question[:type] = q['type']
94
+ question[:question] = q['question']
95
+ question[:answer_key], question[:answers] = randomize_answers(q['correct_answer'], q['incorrect_answers'])
96
+
97
+ @generator&.update_answer_key(question)
98
+
99
+ questions.append(question)
100
+ end
101
+ questions
102
+ end
103
+
104
+ #
105
+ # Randomize the order of the correct and incorrect answers.
106
+ #
107
+ # @param [string] correct correct answer
108
+ # @param [array] incorrect incorrect answers
109
+ #
110
+ # @return [array] zero-based index of the correct answer and array of all answers
111
+ #
112
+ def randomize_answers(correct, incorrect)
113
+ answers = incorrect.append(correct).shuffle
114
+ location = answers.find_index(correct)
115
+ [location, answers]
116
+ end
117
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: open_trivia_db
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Paul Seto
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-06-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Retrieve questions from Open Trivia DB
14
+ email: pseto@openlava.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/category_text_key_generator.rb
20
+ - lib/generate_answer_key.rb
21
+ - lib/leading_digits_key_generator.rb
22
+ - lib/open_trivia_db.rb
23
+ homepage: https://github.com/paulseto/open_trivia_db
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '3'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubygems_version: 3.2.3
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Quiz questions based on the Open Trivia DB
46
+ test_files: []