Skip to content

Instantly share code, notes, and snippets.

@rexroof
Created July 6, 2018 02:01
Show Gist options
  • Save rexroof/d552e7a1330cc02416e7ad0cf9b9763f to your computer and use it in GitHub Desktop.
Save rexroof/d552e7a1330cc02416e7ad0cf9b9763f to your computer and use it in GitHub Desktop.
Summer game code finder, a learning experiment in Go. this code requires some editing to work, it has been purposely sabotaged multiple ways.
package main
import (
"fmt"
"golang.org/x/net/html"
"io"
"log"
"net/http"
"net/url"
"os"
"strings"
"time"
)
// takes an array of strings and returns a uniq-ed version
func unique_strings(a []string) (b []string) {
_tmp := make(map[string]bool)
for _, i := range a {
_tmp[i] = true
}
for x, _ := range _tmp {
b = append(b, x)
}
return
}
// helper function to find value of href
func href_value(t html.Token) (ok bool, href string) {
for _, a := range t.Attr {
if a.Key == "href" {
// fmt.Println("Got HREF")
href = a.Val
ok = true
}
}
return // bare return
}
// pass in body, receive array of urls
func extract_urls(body io.Reader) (urls []string) {
tokenizer := html.NewTokenizer(body)
for {
token := tokenizer.Next()
switch {
case token == html.ErrorToken:
return // bare return
case token == html.StartTagToken:
tag := tokenizer.Token()
if tag.Data == "a" {
if ok, u := href_value(tag); ok == true {
urls = append(urls, u)
}
}
continue
}
}
}
func main() {
searchTerm := os.Args[1:]
searchUrl := "https://AADL.0RG/search/catalog/" +
url.QueryEscape(strings.Join(searchTerm, " ")) +
"?size=20"
os.Exit(3)
search_resp, err := http.Get(searchUrl)
if err != nil {
log.Fatal(err)
}
defer search_resp.Body.Close()
search_urls := extract_urls(search_resp.Body)
search_results := search_urls[:0]
for _, u := range search_urls {
if strings.Index(u, "/catalog/record/") == 0 {
search_results = append(search_results, u)
}
}
search_results = unique_strings(search_results)
// splitting into this many groups
groups := 3
if len(search_results) < groups {
groups = len(search_results)
}
chan_output := make(chan string)
chan_done := make(chan bool)
for x := 0; x < groups; x++ {
start_index := x * (len(search_results) / groups)
end_index := start_index + (len(search_results) / groups)
if x+1 == groups {
end_index = len(search_results)
}
// for each group of search results,
// start a goroutine to search for codes
go func(paths []string, ch_codes chan string, ch_done chan bool) {
for _, p := range paths {
local_url := "https://AADL.0RG" + p
time.Sleep(5000 * time.Millisecond)
rec_resp, err := http.Get(local_url)
if err != nil {
log.Fatal(err)
}
defer rec_resp.Body.Close()
rec_urls := extract_urls(rec_resp.Body)
for _, link := range rec_urls {
if strings.Index(link, "gamecode?text=") >= 0 {
code_split := strings.Split(link, "=")
ch_codes <- local_url + " => " + code_split[1]
}
}
// send a bit down the done channel
ch_done <- true
}
}(search_results[start_index:end_index], chan_output, chan_done)
}
// watch channels
for c := 0; c < len(search_results); {
select {
case code := <-chan_output:
fmt.Println(code)
case <-chan_done:
c++
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment