Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d16ebb8a1 | ||
|
|
2c2cfc126c | ||
|
|
7e18005473 | ||
|
|
81ae0c433b | ||
|
|
9938ae06f6 | ||
|
|
2e99708417 | ||
|
|
d9009cdbaa |
No files matched your search
@@ -13,6 +13,7 @@
|
||||
* helper function to do the whole crawl process
|
||||
* document code better
|
||||
* test with godoc
|
||||
* omit fields in json when nil? (Broken, etc.)
|
||||
|
||||
## Features
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
// docrawl begins crawling the site at "homeurl"
|
||||
func docrawl(homeurl string) itemSlice {
|
||||
// set of what we have already crawled
|
||||
crawled := make(map[string]struct{})
|
||||
crawled := make(itemMap)
|
||||
|
||||
// map (of urlString -> httpItem) of our results
|
||||
results := make(itemMap)
|
||||
@@ -31,7 +31,7 @@ func docrawl(homeurl string) itemSlice {
|
||||
crawlingCount := 1
|
||||
|
||||
// start the home page crawl
|
||||
crawled[homeitem.url.String()] = struct{}{}
|
||||
crawled[homeitem.url.String()] = homeitem
|
||||
go crawlItem(homeitem, rchan)
|
||||
|
||||
// wait for results
|
||||
@@ -46,19 +46,24 @@ func docrawl(homeurl string) itemSlice {
|
||||
|
||||
// start crawly any new child pages we haven't yet crawled
|
||||
for i, c := range r.children {
|
||||
// see if we already have a result for this page, if so, point to that result
|
||||
// see if we already have a result for this page
|
||||
// if so, point to that result
|
||||
if existing, ok := results[c.url.String()]; ok {
|
||||
r.children[i] = existing
|
||||
continue
|
||||
}
|
||||
|
||||
// see if we're already crawling this page (but maybe don't have results yet)
|
||||
if _, ok := crawled[c.url.String()]; !ok {
|
||||
// haven't crawled this one yet, do so now
|
||||
crawlingCount++
|
||||
crawled[c.url.String()] = struct{}{}
|
||||
go crawlItem(c, rchan)
|
||||
// if so, point to that item (we will have it as a result later!)
|
||||
if existing, ok := crawled[c.url.String()]; ok {
|
||||
r.children[i] = existing
|
||||
continue
|
||||
}
|
||||
|
||||
// haven't crawled this one yet, do so now
|
||||
crawlingCount++
|
||||
crawled[c.url.String()] = c
|
||||
go crawlItem(c, rchan)
|
||||
}
|
||||
|
||||
case <-ticker: // our regular ticker. for status output and checking for completion.
|
||||
|
||||
@@ -102,7 +102,7 @@ func TestSimpleMap(t *testing.T) {
|
||||
t.Logf("got %v, wanted %v\n", len(pages), 6)
|
||||
t.Fatal("got wrong number of pages")
|
||||
}
|
||||
if children != 8 {
|
||||
if children != 9 {
|
||||
t.Logf("got %v, wanted %v\n", children, 8)
|
||||
t.Fatal("got wrong number of total children")
|
||||
}
|
||||
@@ -117,7 +117,7 @@ func TestSimpleMap(t *testing.T) {
|
||||
}
|
||||
|
||||
// specific page number of children
|
||||
if len(homepage.children) != 4 {
|
||||
if len(homepage.children) != 5 {
|
||||
t.Logf("got %v, wanted %v\n", len(homepage.children), 4)
|
||||
t.Fatal("got wrong number of links")
|
||||
}
|
||||
|
||||
+10
-2
@@ -48,12 +48,20 @@ func sitemapToLocations(pages itemSlice) []*Location {
|
||||
l.Links = append(l.Links, c.url.String())
|
||||
} else if c.linkType == tBroken {
|
||||
l.Broken = append(l.Broken, c.url.String())
|
||||
} else {
|
||||
} else if c.linkType == tAsset {
|
||||
l.Assets = append(l.Assets, c.url.String())
|
||||
} else {
|
||||
// unknown link here, which means it failed to crawl, let's call it "broken"
|
||||
l.Broken = append(l.Broken, c.url.String())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// now sort the children slices
|
||||
// now uniq & sort the children slices
|
||||
l.Remote = uniqStrings(l.Remote)
|
||||
l.Links = uniqStrings(l.Links)
|
||||
l.Broken = uniqStrings(l.Broken)
|
||||
l.Assets = uniqStrings(l.Assets)
|
||||
sort.Strings(l.Remote)
|
||||
sort.Strings(l.Links)
|
||||
sort.Strings(l.Broken)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<body>
|
||||
<img src="/assets/image.png"/>
|
||||
<a href="/about.html">fooey!</a>
|
||||
<a href="/about.html">duplicate!</a>
|
||||
<script src="scripts/blah.js"/>
|
||||
<a href="/zzzbroken.html">oops!</a>
|
||||
</body>
|
||||
|
||||
@@ -49,3 +49,12 @@ func resolveURL(referringURL string, currentURL string) (*url.URL, error) {
|
||||
// return the URL we ended up with, and the error from checkURL
|
||||
return uResolved, checkURL(uResolved)
|
||||
}
|
||||
|
||||
func stripAnchorFromURL(u *url.URL) string {
|
||||
// copy the url locally
|
||||
ucopy := *u
|
||||
|
||||
// blank out the anchor, return URI string
|
||||
ucopy.Fragment = ""
|
||||
return ucopy.String()
|
||||
}
|
||||
@@ -68,3 +68,14 @@ func TestBadResolve(t* testing.T) {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func TestURLStripAnchor(t *testing.T) {
|
||||
u, err := url.Parse("http://swaits:pass@somehost.com:8765/blah/blah.html?x=y#foo")
|
||||
if err != nil {
|
||||
t.Fatal("couldn't parse a URL")
|
||||
}
|
||||
stripped := stripAnchorFromURL(u)
|
||||
if stripped != "http://swaits:pass@somehost.com:8765/blah/blah.html?x=y" {
|
||||
t.Error("stripping anchor #foo from URL failed")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
// uniqStrings takes a slice of strings and removes any duplicates
|
||||
// note: does not guarantee any order (or stability of order)
|
||||
func uniqStrings(strs []string) []string {
|
||||
// handle special case of a nil parameter
|
||||
if strs == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// add each string to the slice as keys (used like a "set")
|
||||
set := make(map[string]struct{})
|
||||
for _, s := range strs {
|
||||
set[s] = struct{}{}
|
||||
}
|
||||
|
||||
// now copy all the keys over to a new slice and return it
|
||||
result := []string{}
|
||||
for key := range set {
|
||||
result = append(result, key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUniqStrings(t *testing.T) {
|
||||
strs := []string{"a", "a", "b", "a", "b", "c", "d", "a", "b", "e", "d"}
|
||||
uniq := uniqStrings(strs)
|
||||
if len(uniq) != 5 {
|
||||
t.Error("wrong number of strings after uniq'ing")
|
||||
}
|
||||
sort.Strings(uniq)
|
||||
if uniq[0] != "a" || uniq[1] != "b" || uniq[2] != "c" || uniq[3] != "d" || uniq[4] != "e" {
|
||||
t.Error("uniq values are in correct!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUniqStringsNilParm(t *testing.T) {
|
||||
uniq := uniqStrings(nil)
|
||||
if uniq != nil {
|
||||
t.Error("uniqStrings should return a nil slice when passed a nil slice")
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -2,6 +2,6 @@
|
||||
|
||||
# colorize the output of "go test"
|
||||
|
||||
sed ''/ok/s//$(printf "\033[32;1m&\033[0m")/'' | \
|
||||
sed ''/^ok/s//$(printf "\033[32;1m&\033[0m")/'' | \
|
||||
sed ''/PASS/s//$(printf "\033[32;1m&\033[0m")/'' | \
|
||||
sed ''/FAIL/s//$(printf "\033[31;1m&\033[0m")/''
|
||||
Reference in new issue
Block a user