package main
import (
"bufio"
"fmt"
"html/template"
"net/http"
"net/http/cgi"
"os"
"os/exec"
"strings"
"time"
)
type Result struct {
Name string
Version string
URL string
}
type ResultPage struct {
Query string
NumResults int
Time string
Results []Result
}
var resTempl = `
Results
{{.NumResults}} results for {{.Query}} (in {{.Time}})
{{range .Results}}
-
{{.Name}}-{{.Version}}
{{end}}
`
func printError(errCode int, errMsg string) {
fmt.Printf("Status:%d %s\r\n", errCode, errMsg)
fmt.Printf("Content-Type: text/plain\r\n")
fmt.Printf("\r\n%s\r\n", errMsg)
}
func parseLines(s string) []Result {
results := make([]Result, 0, 10)
scanner := bufio.NewScanner(strings.NewReader(s))
for scanner.Scan() {
URL := scanner.Text()
URLParts := strings.Split(URL, "/")
pkgNameVer := strings.Split(URLParts[len(URLParts)-1], ".html")[0]
Name := strings.Split(pkgNameVer, "_")[0]
Version := strings.Split(pkgNameVer, "_")[1]
results = append(results, Result{URL: URL, Name: Name, Version: Version})
}
//fmt.Printf("len(results): %d\n", resSize)
return results
}
func getResults(req http.Request) (ResultPage, error) {
var res ResultPage
req.ParseForm()
searchQuery := req.Form["search"]
if len(searchQuery) < 1 {
printError(503, fmt.Sprintf("Something went wrong in parsing query...\r\n%s\r\n", req.Form))
os.Exit(0)
}
res.Query = searchQuery[0]
startTime := time.Now()
cmd := "grep"
args := []string{res.Query, "index.txt"}
if cmdOut, err := exec.Command(cmd, args...).Output(); err != nil {
//fmt.Printf("error executing command: %s", err)
res.Time = fmt.Sprintf("%s", time.Since(startTime))
return res, nil
} else {
res.Results = parseLines(string(cmdOut[:len(cmdOut)]))
res.NumResults = len(res.Results)
res.Time = fmt.Sprintf("%s", time.Since(startTime))
}
return res, nil
}
func printResults(results ResultPage) {
t, err := template.New("webpage").Parse(resTempl)
if err != nil {
printError(502, "Something went wrong...")
return
}
fmt.Printf("Status: 200 OK\r\n")
fmt.Printf("Content-Type: text/html\r\n")
t.Execute(os.Stdout, results)
}
func main() {
var req *http.Request
var err error
req, err = cgi.Request()
if err != nil {
printError(500, "cannot get requested resource"+err.Error())
return
}
res, err := getResults(*req)
if err != nil {
printError(404, fmt.Sprintf("%s", err))
} else {
printResults(res)
}
}