Merge pull request #13 from sundowndev/refactor/design

Implement new design pattern
pull/15/head
Raphaël 2020-09-05 17:31:36 +02:00 committed by GitHub
commit 9d1d5db24a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 188 additions and 199 deletions

View File

@ -25,7 +25,7 @@ Dorkgen is a dork request generator for popular search engines such as Google Se
## Current status
Version 1 is ongoing but the API is still unstable. **For now, only Google is supported**, *v1.3* will introduce support for other search engines as well as a new design pattern.
Version 1 is ongoing, but the API is still unstable. **For now, only Google's supported**, *v1.3* will introduce support for other search engines as well as a new design pattern.
## Install
@ -37,7 +37,7 @@ go get github.com/sundowndev/dorkgen
## Usage
**[Try it in the Go playground](https://play.golang.org/p/ck_hEoX8cTK)**
**[Try it in the Go playground](https://play.golang.org/p/EoaiowZTr0i)**
#### Get started

30
doc.go
View File

@ -1,35 +1,5 @@
/*
Package dorkgen is a Go package to generate dork requests for popular search engines such as Google, DuckDuckGo and Bing.
It allows you to define requests programmatically and convert them into string.
You can use it as following:
package main
import "github.com/sundowndev/dorkgen"
func main() {
dork := dorkgen.NewGoogleSearch()
// dork := dorkgen.NewDuckDuckGo()
// dork := dorkgen.NewBing()
dork.Site("example.com").Intext("text").String()
// returns: site:example.com "text"
}
// You can also isolate tags between parentheses
func main() {
dork := dorkgen.NewGoogleSearch()
dork.Group(
dorkgen.NewGoogleSearch().
Site("facebook.com")).
Or().
Group(
dorkgen.NewGoogleSearch().
Site("twitter.com")).
Intext("text")
String()
// returns: (site:facebook.com) OR (site:twitter.com) "text"
}
*/
package dorkgen

View File

@ -1,15 +1,7 @@
package dorkgen
// EngineFactory is the main interface for
// search engine implementations.
type EngineFactory struct {
tags []string
}
import "github.com/sundowndev/dorkgen/googlesearch"
func (e *EngineFactory) concat(tag string, value string, quotes bool) string {
if quotes {
return tag + "\"" + value + "\""
}
return tag + value
func NewGoogleSearch() *googlesearch.GoogleSearch {
return googlesearch.New()
}

17
dorkgen_test.go Normal file
View File

@ -0,0 +1,17 @@
package dorkgen
import (
assertion "github.com/stretchr/testify/assert"
"github.com/sundowndev/dorkgen/googlesearch"
"testing"
)
func TestInit(t *testing.T) {
assert := assertion.New(t)
t.Run("should create a GoogleSearch instance", func(t *testing.T) {
dork := NewGoogleSearch()
assert.IsType(&googlesearch.GoogleSearch{}, dork, "they should be equal")
})
}

132
google.go
View File

@ -1,132 +0,0 @@
package dorkgen
import (
"net/url"
"strings"
)
const (
searchURL = "https://www.google.com/search"
siteTag = "site:"
urlTag = "inurl:"
filetypeTag = "filetype:"
cacheTag = "cache:"
relatedTag = "related:"
extTag = "ext:"
excludeTag = "-"
intitleTag = "intitle:"
intextTag = "intext:"
operatorOr = "|"
operatorAnd = "+"
)
// GoogleSearch is the Google search implementation for Dorkgen
type GoogleSearch struct {
EngineFactory
}
func NewGoogleSearch() *GoogleSearch {
return &GoogleSearch{}
}
// String converts all tags to a single request
func (e *GoogleSearch) String() string {
return strings.Join(e.tags, " ")
}
// QueryValues returns search request as URL values
func (e *GoogleSearch) QueryValues() url.Values {
tags := strings.Join(e.tags, " ")
params := url.Values{}
params.Add("q", tags)
return params
}
// URL converts tags to an encoded Google Search URL
func (e *GoogleSearch) URL() string {
baseURL, _ := url.Parse(searchURL)
baseURL.RawQuery = e.QueryValues().Encode()
return baseURL.String()
}
// Site specifically searches that particular site and lists all the results for that site.
func (e *GoogleSearch) Site(site string) *GoogleSearch {
e.tags = append(e.tags, e.concat(siteTag, site, false))
return e
}
// Or puts an OR operator in the request
func (e *GoogleSearch) Or() *GoogleSearch {
e.tags = append(e.tags, operatorOr)
return e
}
// And puts an AND operator in the request
func (e *GoogleSearch) And() *GoogleSearch {
e.tags = append(e.tags, operatorAnd)
return e
}
// Intext searches for the occurrences of keywords all at once or one at a time.
func (e *GoogleSearch) Intext(text string) *GoogleSearch {
e.tags = append(e.tags, e.concat(intextTag, text, true))
return e
}
// Inurl searches for a URL matching one of the keywords.
func (e *GoogleSearch) Inurl(url string) *GoogleSearch {
e.tags = append(e.tags, e.concat(urlTag, url, true))
return e
}
// Filetype searches for a particular filetype mentioned in the query.
func (e *GoogleSearch) Filetype(filetype string) *GoogleSearch {
e.tags = append(e.tags, e.concat(filetypeTag, filetype, true))
return e
}
// Cache shows the version of the web page that Google has in its cache.
func (e *GoogleSearch) Cache(url string) *GoogleSearch {
e.tags = append(e.tags, e.concat(cacheTag, url, true))
return e
}
// Related list web pages that are “similar” to a specified web page.
func (e *GoogleSearch) Related(url string) *GoogleSearch {
e.tags = append(e.tags, e.concat(relatedTag, url, true))
return e
}
// Ext searches for a particular file extension mentioned in the query.
func (e *GoogleSearch) Ext(ext string) *GoogleSearch {
e.tags = append(e.tags, e.concat(extTag, ext, false))
return e
}
// Exclude excludes some results.
func (e *GoogleSearch) Exclude(tags *GoogleSearch) *GoogleSearch {
e.tags = append(e.tags, e.concat(excludeTag, tags.String(), false))
return e
}
// Group isolate tags between parentheses
func (e *GoogleSearch) Group(tags *GoogleSearch) *GoogleSearch {
e.tags = append(e.tags, "("+tags.String()+")")
return e
}
// Intitle searches for occurrences of keywords in title all or one.
func (e *GoogleSearch) Intitle(value string) *GoogleSearch {
e.tags = append(e.tags, e.concat(intitleTag, value, true))
return e
}
// Plain allows you to add additional values as string without any kind of formatting.
func (e *GoogleSearch) Plain(value string) *GoogleSearch {
e.tags = append(e.tags, value)
return e
}

View File

@ -0,0 +1,141 @@
package googlesearch
import (
"net/url"
"strings"
)
const (
searchURL = "https://www.google.com/search"
siteTag = "site:"
urlTag = "inurl:"
filetypeTag = "filetype:"
cacheTag = "cache:"
relatedTag = "related:"
extTag = "ext:"
excludeTag = "-"
intitleTag = "intitle:"
intextTag = "intext:"
operatorOr = "|"
operatorAnd = "+"
)
// GoogleSearch is the Google search implementation for Dorkgen
type GoogleSearch struct {
tags []string
}
// New creates a new instance of GoogleSearch
func New() *GoogleSearch {
return &GoogleSearch{}
}
func (_ *GoogleSearch) concat(tag string, value string, quotes bool) string {
if quotes {
return tag + "\"" + value + "\""
}
return tag + value
}
// String converts all tags to a single request
func (g *GoogleSearch) String() string {
return strings.Join(g.tags, " ")
}
// QueryValues returns search request as URL values
func (g *GoogleSearch) QueryValues() url.Values {
tags := strings.Join(g.tags, " ")
params := url.Values{}
params.Add("q", tags)
return params
}
// URL converts tags to an encoded Google Search URL
func (g *GoogleSearch) URL() string {
baseURL, _ := url.Parse(searchURL)
baseURL.RawQuery = g.QueryValues().Encode()
return baseURL.String()
}
// Site specifically searches that particular site and lists all the results for that site.
func (g *GoogleSearch) Site(site string) *GoogleSearch {
g.tags = append(g.tags, g.concat(siteTag, site, false))
return g
}
// Or puts an OR operator in the request
func (g *GoogleSearch) Or() *GoogleSearch {
g.tags = append(g.tags, operatorOr)
return g
}
// And puts an AND operator in the request
func (g *GoogleSearch) And() *GoogleSearch {
g.tags = append(g.tags, operatorAnd)
return g
}
// Intext searches for the occurrences of keywords all at once or one at a time.
func (g *GoogleSearch) Intext(text string) *GoogleSearch {
g.tags = append(g.tags, g.concat(intextTag, text, true))
return g
}
// Inurl searches for a URL matching one of the keywords.
func (g *GoogleSearch) Inurl(url string) *GoogleSearch {
g.tags = append(g.tags, g.concat(urlTag, url, true))
return g
}
// Filetype searches for a particular filetype mentioned in the query.
func (g *GoogleSearch) Filetype(filetype string) *GoogleSearch {
g.tags = append(g.tags, g.concat(filetypeTag, filetype, true))
return g
}
// Cache shows the version of the web page that Google has in its cache.
func (g *GoogleSearch) Cache(url string) *GoogleSearch {
g.tags = append(g.tags, g.concat(cacheTag, url, true))
return g
}
// Related list web pages that are “similar” to a specified web page.
func (g *GoogleSearch) Related(url string) *GoogleSearch {
g.tags = append(g.tags, g.concat(relatedTag, url, true))
return g
}
// Ext searches for a particular file extension mentioned in the query.
func (g *GoogleSearch) Ext(ext string) *GoogleSearch {
g.tags = append(g.tags, g.concat(extTag, ext, false))
return g
}
// Exclude excludes some results.
func (g *GoogleSearch) Exclude(tags *GoogleSearch) *GoogleSearch {
g.tags = append(g.tags, g.concat(excludeTag, tags.String(), false))
return g
}
// Group isolate tags between parentheses
func (g *GoogleSearch) Group(tags *GoogleSearch) *GoogleSearch {
g.tags = append(g.tags, "("+tags.String()+")")
return g
}
// Intitle searches for occurrences of keywords in title all or one.
func (g *GoogleSearch) Intitle(value string) *GoogleSearch {
g.tags = append(g.tags, g.concat(intitleTag, value, true))
return g
}
// Plain allows you to add additional values as string without any kind of formatting.
func (g *GoogleSearch) Plain(value string) *GoogleSearch {
g.tags = append(g.tags, value)
return g
}

View File

@ -1,20 +1,21 @@
package dorkgen
package googlesearch_test
import (
"fmt"
"github.com/sundowndev/dorkgen/googlesearch"
"net/url"
"testing"
assertion "github.com/stretchr/testify/assert"
)
var dork *GoogleSearch
var dork *googlesearch.GoogleSearch
func TestInit(t *testing.T) {
assert := assertion.New(t)
t.Run("should convert to URL correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Site("example.com").
@ -24,7 +25,7 @@ func TestInit(t *testing.T) {
})
t.Run("should convert to string correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := fmt.Sprint(dork.Site("example.com"))
@ -32,7 +33,7 @@ func TestInit(t *testing.T) {
})
t.Run("should handle site tag correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Site("example.com").
@ -42,7 +43,7 @@ func TestInit(t *testing.T) {
})
t.Run("should handle intext tag correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Intext("text").
@ -52,7 +53,7 @@ func TestInit(t *testing.T) {
})
t.Run("should handle inurl tag correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Inurl("index.php").
@ -62,7 +63,7 @@ func TestInit(t *testing.T) {
})
t.Run("should handle filetype tag correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Filetype("pdf").
@ -72,7 +73,7 @@ func TestInit(t *testing.T) {
})
t.Run("should handle cache tag correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Cache("www.google.com").
@ -82,7 +83,7 @@ func TestInit(t *testing.T) {
})
t.Run("should handle related tag correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Related("www.google.com").
@ -92,7 +93,7 @@ func TestInit(t *testing.T) {
})
t.Run("should handle ext tag correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Ext("(doc | pdf | xls | txt | xml)").
@ -102,20 +103,20 @@ func TestInit(t *testing.T) {
})
t.Run("should handle exclude tag correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Exclude(NewGoogleSearch().Plain("html")).
Exclude(NewGoogleSearch().Plain("htm")).
Exclude(NewGoogleSearch().Plain("php")).
Exclude(NewGoogleSearch().Plain("md5sums")).
Exclude(googlesearch.New().Plain("html")).
Exclude(googlesearch.New().Plain("htm")).
Exclude(googlesearch.New().Plain("php")).
Exclude(googlesearch.New().Plain("md5sums")).
String()
assert.Equal(result, "-html -htm -php -md5sums", "they should be equal")
})
t.Run("should handle 'OR' tag correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Site("facebook.com").
@ -127,7 +128,7 @@ func TestInit(t *testing.T) {
})
t.Run("should handle 'AND' tag correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Intitle("facebook").
@ -139,22 +140,22 @@ func TestInit(t *testing.T) {
})
t.Run("should handle group tag correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Site("linkedin.com").
Group((NewGoogleSearch()).Intext("1").Or().Intext("2")).
Group(googlesearch.New().Intext("1").Or().Intext("2")).
String()
assert.Equal(result, "site:linkedin.com (intext:\"1\" | intext:\"2\")", "they should be equal")
})
t.Run("should handle group tag correctly", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Site("linkedin.com").
Group((NewGoogleSearch()).Intext("1").Or().Intext("2")).
Group(googlesearch.New().Intext("1").Or().Intext("2")).
Intitle("jordan").
String()
@ -162,11 +163,11 @@ func TestInit(t *testing.T) {
})
t.Run("should return URL values", func(t *testing.T) {
dork = NewGoogleSearch()
dork = googlesearch.New()
result := dork.
Site("linkedin.com").
Group((NewGoogleSearch()).Intext("1").Or().Intext("2")).
Group(googlesearch.New().Intext("1").Or().Intext("2")).
Intitle("jordan").
QueryValues()