Skip to content

Commit 4f2e37c

Browse files
committed
0.9.0 NEW Random Data API
1 parent eb2eea1 commit 4f2e37c

File tree

11 files changed

+358
-113
lines changed

11 files changed

+358
-113
lines changed

README.md

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11

2-
![Version](https://img.shields.io/badge/version-0.8.5-orange.svg)
2+
![Version](https://img.shields.io/badge/version-0.9.0-orange.svg)
33
![Maintained YES](https://img.shields.io/badge/Maintained%3F-yes-green.svg)
44
![Ask Me Anything !](https://img.shields.io/badge/Ask%20me-anything-1abc9c.svg)
55

66
# ![logo](https://github.com/jolav/codetabs/blob/master/www/_public/icons/ct/ct64r.png?raw=true) **ONLINE TOOLS ([codetabs.com](https://codetabs.com))**
77

8-
**version 0.8.5**
8+
**version 0.9.0**
99

1010
1. [Count LOC (lines of code) online from github/gitlab repos or zipped uploaded folder](#count-loc-online)
1111
2. [CORS proxy](#cors-proxy)
@@ -15,6 +15,7 @@
1515
6. [HTTP Headers](#headers)
1616
7. [API weather temp](#weather)
1717
8. [Video To Gif](#video2gif)
18+
9. [Random Data API](#random-data-api)
1819

1920

2021
[To Do List](#to-do)
@@ -233,6 +234,43 @@ Scale : Set width:height , if one parameter is -1 it will automatically determin
233234
234235
<hr>
235236

237+
![logo](https://github.com/jolav/codetabs/blob/master/www/_public/icons/random48.png?raw=true)
238+
239+
## **RANDOM DATA API**
240+
241+
### **[Demo and Docs online](https://codetabs.com/random-data/random-data.html)**
242+
243+
- Api to generate random data
244+
- Only suppports GET request.
245+
- Limit : 10 request per seconds. Once reached subsequent requests will result in error 429 (too many requests) until your quota is cleared.
246+
247+
248+
### **Endpoints**
249+
250+
- Get Random Integers
251+
```
252+
http Request :
253+
GET https://api.codetabs.com/v1/random/integer?range=X-Y
254+
```
255+
256+
Examples
257+
Get random number between 1-10 both inclusive
258+
https://api.codetabs.com/v1/random/integer?min=1&max=10
259+
You can also specify how many times you want the result with the parameter times.
260+
Default is 1 and there is no need to specify it. Max times = 10.000
261+
https://api.codetabs.com/v1/random/integer?min=1&max=10&times=50
262+
263+
- List with randomized order
264+
```
265+
http Request :
266+
GET https://api.codetabs.com/v1/random/list?len=X
267+
```
268+
Max list elements : 10.000
269+
Example: Get random order numbers for a list of 1000 elements
270+
https://api.codetabs.com/v1/random/list?len=1000
271+
272+
<hr>
273+
236274
## TO DO
237275

238276
- [ ] **WWW** clean unused parts, css, etc

_utils/utils.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ func SliceContainsString(str string, slice []string) bool {
2626
return false
2727
}
2828

29+
// SliceContainsInteger ... returns true/false
30+
func SliceContainsInteger(num int, slice []int) bool {
31+
for _, v := range slice {
32+
if v == num {
33+
return true
34+
}
35+
}
36+
return false
37+
}
38+
2939
// GenericCommandSH ...
3040
func GenericCommandSH(comm string) (chunk []byte, err error) {
3141
chunk, err = exec.Command("sh", "-c", comm).CombinedOutput()
@@ -35,6 +45,16 @@ func GenericCommandSH(comm string) (chunk []byte, err error) {
3545
return chunk, err
3646
}
3747

48+
// RemoveElementFromSliceString
49+
func RemoveElementFromSliceString(index int, slice []string) []string {
50+
return append(slice[:index], slice[index+1:]...)
51+
}
52+
53+
// RemoveElementFromSliceInt
54+
func RemoveElementFromSliceInt(index int, slice []int) []int {
55+
return append(slice[:index], slice[index+1:]...)
56+
}
57+
3858
// GenericCommand ...
3959
func GenericCommand(args []string) (err error) {
4060
_, err = exec.Command(args[0], args[1:len(args)]...).CombinedOutput()

main.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"flag"
99
"fmt"
1010
"log"
11+
"math/rand"
1112
"net/http"
1213
"os"
1314
"os/user"
@@ -20,13 +21,14 @@ import (
2021
"github.com/jolav/codetabs/headers"
2122
"github.com/jolav/codetabs/loc"
2223
"github.com/jolav/codetabs/proxy"
24+
"github.com/jolav/codetabs/random"
2325
"github.com/jolav/codetabs/stars"
2426
"github.com/jolav/codetabs/store"
2527
"github.com/jolav/codetabs/video2gif"
2628
"github.com/jolav/codetabs/weather"
2729
)
2830

29-
var version = "0.8.5"
31+
var version = "0.9.0"
3032
var when = "undefined"
3133

3234
type Conf struct {
@@ -42,6 +44,8 @@ type Conf struct {
4244
}
4345

4446
func main() {
47+
48+
rand.Seed(time.Now().UnixNano())
4549
checkFlags()
4650

4751
var c Conf
@@ -91,6 +95,7 @@ func main() {
9195
mux.HandleFunc("/v1/headers/", mw(headers.Router, "headers", c))
9296
mux.HandleFunc("/v1/weather/", mw(weather.Router, "weather", c))
9397
mux.HandleFunc("/v1/video2gif/", mw(video2gif.Router, "video2gif", c))
98+
mux.HandleFunc("/v1/random/", mw(random.Router, "random", c))
9499
mux.HandleFunc("/v1/stars/", mw(stars.Router, "stars", c))
95100
mux.HandleFunc("/v1/proxy/", mw(proxy.Router, "proxy", c))
96101
mux.HandleFunc("/v1/tmp/", mw(proxy.Router, "proxy", c))

random/random.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/* */
2+
3+
package random
4+
5+
import (
6+
"fmt"
7+
"net/http"
8+
"strconv"
9+
"strings"
10+
11+
u "github.com/jolav/codetabs/_utils"
12+
)
13+
14+
type random struct {
15+
Quest string `json:"quest"`
16+
Result []int `json:"data"`
17+
}
18+
19+
func Router(w http.ResponseWriter, r *http.Request) {
20+
params := strings.Split(strings.ToLower(r.URL.Path), "/")
21+
path := params[1:len(params)]
22+
if path[len(path)-1] == "" { // remove last empty slot after /
23+
path = path[:len(path)-1]
24+
}
25+
//log.Printf("Going ....%s %s %d", path, r.Method, len(path))
26+
if len(path) < 2 || path[0] != "v1" {
27+
u.BadRequest(w, r)
28+
return
29+
}
30+
if len(path) != 3 {
31+
u.BadRequest(w, r)
32+
return
33+
}
34+
35+
if r.Method == "POST" {
36+
u.BadRequest(w, r)
37+
return
38+
}
39+
40+
rd := newRandom()
41+
randomType := path[2]
42+
switch randomType {
43+
case "integer":
44+
rd.randomInteger(w, r)
45+
case "list":
46+
rd.randomList(w, r)
47+
default:
48+
u.BadRequest(w, r)
49+
return
50+
}
51+
}
52+
53+
func (rd random) randomInteger(w http.ResponseWriter, r *http.Request) {
54+
times := 1
55+
56+
r.ParseForm()
57+
min, err := strconv.Atoi(r.Form.Get("min"))
58+
if err != nil {
59+
u.BadRequest(w, r)
60+
return
61+
}
62+
max, err := strconv.Atoi(r.Form.Get("max"))
63+
if err != nil || min > max || min < 0 || max > 10000000000 {
64+
u.BadRequest(w, r)
65+
return
66+
}
67+
if r.Form.Get("times") != "" {
68+
times, err = strconv.Atoi(r.Form.Get("times"))
69+
if err != nil || times > 10000 {
70+
u.BadRequest(w, r)
71+
return
72+
}
73+
}
74+
if times == 1 {
75+
rd.Quest = fmt.Sprintf("Random Integer between %d-%d", min, max)
76+
} else {
77+
rd.Quest = fmt.Sprintf("%d Random Integers between %d-%d", times, min, max)
78+
}
79+
80+
for time := 1; time <= times; time++ {
81+
rd.Result = append(rd.Result, u.GetRandomInt(min, max))
82+
}
83+
84+
u.SendJSONToClient(w, rd, 200)
85+
}
86+
87+
func (rd random) randomList(w http.ResponseWriter, r *http.Request) {
88+
r.ParseForm()
89+
elements, err := strconv.Atoi(r.Form.Get("len"))
90+
if err != nil || elements < 2 || elements > 10000 {
91+
u.BadRequest(w, r)
92+
return
93+
}
94+
95+
rd.Quest = fmt.Sprintf("Randomized order list with %d elements", elements)
96+
element := 0
97+
for element < elements {
98+
number := u.GetRandomInt(1, elements)
99+
if !u.SliceContainsInteger(number, rd.Result) {
100+
rd.Result = append(rd.Result, number)
101+
element++
102+
}
103+
}
104+
u.SendJSONToClient(w, rd, 200)
105+
}
106+
107+
func newRandom() random {
108+
rd := random{
109+
Quest: "",
110+
Result: []int{},
111+
}
112+
return rd
113+
}

www/_public/icons/random48.png

995 Bytes
Loading

www/_public/images/sprite.png

259 Bytes
Loading

www/_public/sprites/random32.png

686 Bytes
Loading

www/_public/templates/version.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<h2 class="centerText">
33
API doc
44
<small>
5-
<small>(version 0.8.5)</small>
5+
<small>(version 0.9.0)</small>
66
</small>
77
</h2>
88
<!-- End -->

www/index.css

Lines changed: 21 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -229,95 +229,24 @@ hr {
229229
}
230230

231231
/* Generated by http://css.spritegen.com CSS Sprite Generator */
232-
233-
.ct64r, .ct48r, .alexa32, .ct32r, .gif32, .headers32, .ip32, .jolav32, .loc32, .notes32, .proxy32, .stars32, .weather32, .check {
234-
display: inline-block;
235-
background: url('/_public/images/sprite.png') no-repeat;
236-
overflow: hidden;
237-
text-indent: -9999px;
238-
text-align: left;
239-
}
240-
241-
.ct64r {
242-
background-position: -0px -0px;
243-
width: 64px;
244-
height: 64px;
245-
}
246-
247-
.ct48r {
248-
background-position: -0px -64px;
249-
width: 48px;
250-
height: 48px;
251-
}
252-
253-
.alexa32 {
254-
background-position: -0px -112px;
255-
width: 32px;
256-
height: 32px;
257-
}
258-
259-
.ct32r {
260-
background-position: -32px -112px;
261-
width: 32px;
262-
height: 32px;
263-
}
264-
265-
.gif32 {
266-
background-position: -0px -144px;
267-
width: 32px;
268-
height: 32px;
269-
}
270-
271-
.headers32 {
272-
background-position: -32px -144px;
273-
width: 32px;
274-
height: 32px;
275-
}
276-
277-
.ip32 {
278-
background-position: -0px -176px;
279-
width: 32px;
280-
height: 32px;
281-
}
282-
283-
.jolav32 {
284-
background-position: -32px -176px;
285-
width: 32px;
286-
height: 32px;
287-
}
288-
289-
.loc32 {
290-
background-position: -0px -208px;
291-
width: 32px;
292-
height: 32px;
293-
}
294-
295-
.notes32 {
296-
background-position: -32px -208px;
297-
width: 32px;
298-
height: 32px;
299-
}
300-
301-
.proxy32 {
302-
background-position: -0px -240px;
303-
width: 32px;
304-
height: 32px;
305-
}
306-
307-
.stars32 {
308-
background-position: -32px -240px;
309-
width: 32px;
310-
height: 32px;
311-
}
312-
313-
.weather32 {
314-
background-position: -0px -272px;
315-
width: 32px;
316-
height: 32px;
317-
}
318-
319-
.check {
320-
background-position: -48px -64px;
321-
width: 16px;
322-
height: 16px;
323-
}
232+
233+
.ct64r, .ct48r, .alexa32, .ct32r, .gif32,
234+
.headers32, .ip32, .jolav32, .loc32, .notes32,
235+
.proxy32, .random32, .stars32, .weather32, .check
236+
{ display: inline-block; background: url('_public/images/sprite.png') no-repeat; overflow: hidden; text-indent: -9999px; text-align: left; }
237+
238+
.ct64r { background-position: -0px -0px; width: 64px; height: 64px; }
239+
.ct48r { background-position: -0px -64px; width: 48px; height: 48px; }
240+
.alexa32 { background-position: -0px -112px; width: 32px; height: 32px; }
241+
.ct32r { background-position: -32px -112px; width: 32px; height: 32px; }
242+
.gif32 { background-position: -0px -144px; width: 32px; height: 32px; }
243+
.headers32 { background-position: -32px -144px; width: 32px; height: 32px; }
244+
.ip32 { background-position: -0px -176px; width: 32px; height: 32px; }
245+
.jolav32 { background-position: -32px -176px; width: 32px; height: 32px; }
246+
.loc32 { background-position: -0px -208px; width: 32px; height: 32px; }
247+
.notes32 { background-position: -32px -208px; width: 32px; height: 32px; }
248+
.proxy32 { background-position: -0px -240px; width: 32px; height: 32px; }
249+
.random32 { background-position: -32px -240px; width: 32px; height: 32px; }
250+
.stars32 { background-position: -0px -272px; width: 32px; height: 32px; }
251+
.weather32 { background-position: -32px -272px; width: 32px; height: 32px; }
252+
.check { background-position: -48px -64px; width: 16px; height: 16px; }

0 commit comments

Comments
 (0)