Created
July 6, 2018 02:01
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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