1 package main 2 3 import ( 4 "encoding/json" 5 "errors" 6 "flag" 7 "fmt" 8 "net/http" 9 "os" 10 ) 11 12 func main() { 13 if err := run(); err != nil { 14 fmt.Fprintln(os.Stderr, err) 15 os.Exit(1) 16 } 17 } 18 19 // Question contains all of the data for a single question 20 type Question struct { 21 Category string `json:"category"` 22 Type string `json:"type"` 23 Difficulty string `json:"difficulty"` 24 Question string `json:"question"` 25 CorrectAnswer string `json:"correct_answer"` 26 IncorrectAnswers []string `json:"incorrect_answers"` 27 } 28 29 const ( 30 easy = "ZWFzeQ==" 31 medium = "bWVkaXVt" 32 hard = "aGFyZA==" 33 boolean = "Ym9vbGVhbg==" 34 multiple = "bXVsdGlwbGU=" 35 booleanTrue = "VHJ1ZQ==" 36 ) 37 38 func run() error { 39 var output string 40 flag.StringVar(&output, "o", "otdb.js", "Output file") 41 flag.Parse() 42 f, err := os.Create(output) 43 if err != nil { 44 return err 45 } 46 resp, err := http.DefaultClient.Get("https://opentdb.com/api_count_global.php") 47 if err != nil { 48 return err 49 } 50 var amount struct { 51 Overall struct { 52 Num int `json:"total_num_of_verified_questions"` 53 } `json:"overall"` 54 } 55 if err := json.NewDecoder(resp.Body).Decode(&amount); err != nil { 56 return err 57 } 58 fmt.Printf("Amount to Get: %d\n", amount.Overall.Num) 59 resp, err = http.DefaultClient.Get("https://opentdb.com/api_token.php?command=request") 60 if err != nil { 61 return err 62 } 63 var token struct { 64 ResponseCode uint8 `json:"response_code"` 65 ResponseMessage string `json:"response_message"` 66 Token string `json:"token"` 67 } 68 if err := json.NewDecoder(resp.Body).Decode(&token); err != nil { 69 return err 70 } 71 if token.ResponseCode != 0 { 72 return errors.New(token.ResponseMessage) 73 } 74 tk := "&token=" + token.Token 75 num := "50" 76 got := 0 77 var questions struct { 78 ResponseCode uint8 `json:"response_code"` 79 Results []Question `json:"results"` 80 } 81 if _, err := f.WriteString("export const qs = ["); err != nil { 82 return err 83 } 84 categories := make(map[string]int) 85 catID := 0 86 for amount.Overall.Num > 0 { 87 if amount.Overall.Num < 50 { 88 num = fmt.Sprintf("%d", amount.Overall.Num) 89 } 90 fmt.Printf("\rGot %d results...", got) 91 resp, err := http.DefaultClient.Get("https://opentdb.com/api.php?amount=" + num + "&encode=base64" + tk) 92 if err != nil { 93 return err 94 } 95 if err := json.NewDecoder(resp.Body).Decode(&questions); err != nil { 96 return err 97 } 98 switch questions.ResponseCode { 99 case 0: 100 fmt.Printf("retrieved %d more results ", len(questions.Results)) 101 for _, q := range questions.Results { 102 typ := 0 103 switch q.Type { 104 case boolean: 105 typ = 0 106 case multiple: 107 typ = 1 108 default: 109 continue 110 } 111 difficulty := 0 112 switch q.Difficulty { 113 case easy: 114 difficulty = 0 115 case medium: 116 difficulty = 1 117 case hard: 118 difficulty = 2 119 default: 120 continue 121 } 122 cID, ok := categories[q.Category] 123 if !ok { 124 cID = catID 125 catID++ 126 categories[q.Category] = cID 127 } 128 if got > 0 { 129 if _, err := f.WriteString(","); err != nil { 130 return err 131 } 132 } 133 got++ 134 if _, err := fmt.Fprintf(f, "[%d,%d,%d,%q,", typ, difficulty, cID, q.Question); err != nil { 135 return err 136 } 137 if typ == 1 { 138 fmt.Fprintf(f, "%q", q.CorrectAnswer) 139 for _, a := range q.IncorrectAnswers { 140 if _, err := f.WriteString(","); err != nil { 141 return err 142 } 143 if _, err := fmt.Fprintf(f, "%q", a); err != nil { 144 return err 145 } 146 } 147 } else if q.CorrectAnswer == booleanTrue { 148 if _, err := f.WriteString("1"); err != nil { 149 return err 150 } 151 } else { 152 if _, err := f.WriteString("0"); err != nil { 153 return err 154 } 155 } 156 if _, err := f.WriteString("]"); err != nil { 157 return err 158 } 159 } 160 amount.Overall.Num -= len(questions.Results) 161 questions.Results = questions.Results[:0] 162 case 1: 163 return errors.New("no results") 164 case 2: 165 return errors.New("invalid parameter") 166 case 3: 167 return errors.New("token not found") 168 case 4: 169 return errors.New("token empty") 170 default: 171 return errors.New("unknown error") 172 } 173 } 174 if _, err := f.WriteString("], cats = ["); err != nil { 175 return err 176 } 177 first := true 178 for cat := range categories { 179 if first { 180 first = false 181 } else { 182 if _, err := f.WriteString(","); err != nil { 183 return err 184 } 185 } 186 if _, err := fmt.Fprintf(f, "%q", cat); err != nil { 187 return err 188 } 189 } 190 if _, err := f.WriteString("];"); err != nil { 191 return err 192 } 193 return f.Close() 194 }