-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserver.go
131 lines (109 loc) · 2.86 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package main
import (
"bufio"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"strconv"
"strings"
"time"
cache "github.com/patrickmn/go-cache"
)
const (
seperator = ":"
port = "8080"
VenvCmd = "source scraper/venv/bin/activate"
PyCmd = "python scraper/scraper.py"
TimedOut = "{ error : 'Request timed out' }"
)
var (
c = cache.New(5*time.Minute, 10*time.Minute)
)
type client struct {
RegNo string
Password string
ID int64
Json string
}
func Handler(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
log.Printf("Recieved %s request. Invalid", r.Method)
fmt.Fprintf(w, "Invalid request")
return
}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
w.Header().Set("Access-Control-Expose-Headers", "Authorization")
if r.FormValue("regno") == "" || r.FormValue("password") == "" {
log.Printf("Recieved blank param values")
return
}
fmt.Println("\n--- New Request ---")
defer fmt.Println("\n-------------------")
unique_id := time.Now().Unix()
curr := &client{} // Current client
curr.RegNo = r.FormValue("regno")
curr.Password = r.FormValue("password")
curr.ID = unique_id
Json, found := c.Get(curr.RegNo) // Check cache
if found {
log.Printf("Found JSON in cache for user %s", curr.RegNo)
fmt.Fprintf(w, Json.(string)) // If response found in cache, print it
return
} else {
log.Printf("Couldn't find user in cache, running scraper")
err := curr.Run() // Set the clients data (Invoke scraper)
if err != nil {
log.Printf("Encountered error while scraping %s", err.Error())
curr.Json = err.Error()
fmt.Fprintf(w, curr.Json)
return
}
if strings.Compare(curr.Json, TimedOut) != 0 { // Don't cache failed responses (Wrong credentials)
c.Set(curr.RegNo, curr.Json, cache.DefaultExpiration) // Set cache
}
log.Println("Successfully printed json")
fmt.Fprintf(w, curr.Json) // Print json
}
}
func (c *client) Run() error {
filePath := "results/" + strconv.FormatInt(c.ID, 10) + ".json"
defer func() {
_, err := os.Stat(filePath)
if err != nil {
log.Println("Json file doesn't exist")
} else {
os.Remove(filePath)
}
}()
command := fmt.Sprintf("%s; %s %s %s %s;", VenvCmd, PyCmd, c.RegNo, c.Password, filePath)
cmd := exec.Command("sh", "-c", command)
stderr, err := cmd.StderrPipe()
if err != nil {
return err // To do : Send custom error along with stderr log
}
if err := cmd.Start(); err != nil {
return err
}
in := bufio.NewScanner(stderr)
for in.Scan() {
log.Printf(in.Text())
}
if err := in.Err(); err != nil {
log.Printf("error : %s", err)
}
dat, err := ioutil.ReadFile(filePath)
if err != nil {
return err
}
c.Json = string(dat)
return nil
}
func main() {
addr := seperator + port
http.HandleFunc("/", Handler)
log.Fatal(http.ListenAndServe(addr, nil))
}