Skip to content

Commit

Permalink
added language heuristic to cheat.sh
Browse files Browse the repository at this point in the history
  • Loading branch information
spy16 committed Sep 23, 2018
1 parent 2868c06 commit 1f144fe
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 94 deletions.
11 changes: 7 additions & 4 deletions cmd/radium/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"context"
"errors"
"fmt"
"os"
"strings"

Expand All @@ -21,7 +22,7 @@ func newQueryCmd(cfg *config) *cobra.Command {
var attribs []string
var strategy string
cmd.Flags().StringSliceVarP(&attribs, "attr", "a", []string{}, "Attributes to narrow the search scope")
cmd.Flags().StringVarP(&strategy, "strategy", "s", "concurrent", "Strategy to use for executing sources")
cmd.Flags().StringVarP(&strategy, "strategy", "s", "1st", "Strategy to use for executing sources")

cmd.Run = func(_ *cobra.Command, args []string) {
query := radium.Query{}
Expand All @@ -32,8 +33,10 @@ func newQueryCmd(cfg *config) *cobra.Command {
parts := strings.Split(attrib, ":")
if len(parts) == 2 {
query.Attribs[parts[0]] = parts[1]
} else if len(parts) == 1 {
query.Attribs[parts[0]] = "true"
} else {
writeOut(cmd, errors.New("invalid attrib format. must be <name>:<value>"))
writeOut(cmd, errors.New("invalid attrib format. must be <name>[:<value>]"))
os.Exit(1)
}
}
Expand All @@ -46,8 +49,8 @@ func newQueryCmd(cfg *config) *cobra.Command {
os.Exit(1)
}

if len(rs) == 1 {
writeOut(cmd, rs[0])
if len(rs) == 0 {
fmt.Println("No results found")
} else {
writeOut(cmd, rs)
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/radium/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/shivylp/radium"
"github.com/shivylp/radium/sources"
"github.com/shivylp/radium/sources/cheatsh"
)

func getNewRadiumInstance(cfg config) *radium.Instance {
Expand All @@ -13,7 +14,7 @@ func getNewRadiumInstance(cfg config) *radium.Instance {
for _, src := range cfg.Sources {
switch strings.ToLower(strings.TrimSpace(src)) {
case "cheatsh", "cheat.sh":
ins.RegisterSource("cheat.sh", sources.NewCheatSh())
ins.RegisterSource("cheat.sh", cheatsh.New())
case "learnxiny", "lxy", "learnxinyminutes":
ins.RegisterSource("learnxinyminutes", sources.NewLearnXInYMins())
case "tldr":
Expand Down
11 changes: 9 additions & 2 deletions cmd/radium/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,19 @@ func writeOut(cmd *cobra.Command, v interface{}) {

func tryPrettyPrint(v interface{}) {
switch v.(type) {
case radium.Article:
case radium.Article, *radium.Article:
fmt.Println((v.(radium.Article)).Content)
case []radium.Article:
results := v.([]radium.Article)
if len(results) == 1 {
tryPrettyPrint(results[0])
} else {
rawDump(results, false)
}
case error:
fmt.Printf("error: %s\n", v)
default:
rawDump(v, true)
rawDump(v, false)
}
}

Expand Down
87 changes: 0 additions & 87 deletions sources/cheatsh.go

This file was deleted.

26 changes: 26 additions & 0 deletions sources/cheatsh/cheatsh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cheatsh

import (
"context"

"github.com/shivylp/radium"
)

// New initializes a radium.Source implementation using http://cheat.sh as
// the source
func New() *CheatSh {
csh := &CheatSh{}
return csh
}

// CheatSh implements radium.Source interface using cheat.sh as the source
type CheatSh struct {
}

// Search performs an HTTP request to http://cheat.sh to find results matching
// the given query.
func (csh CheatSh) Search(ctx context.Context, query radium.Query) ([]radium.Article, error) {
transformLanguageQuery(&query)

return executeRequest(ctx, query)
}
94 changes: 94 additions & 0 deletions sources/cheatsh/request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package cheatsh

import (
"context"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"path/filepath"
"strings"

"github.com/shivylp/radium"
)

const cheatShURL = "http://cheat.sh"

func executeRequest(ctx context.Context, query radium.Query) ([]radium.Article, error) {
req, err := makeRequest(ctx, query)
if err != nil {
return nil, err
}

client := http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf(resp.Status)
}

data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}

return makeResponse(query, data), nil
}

func makeResponse(query radium.Query, data []byte) []radium.Article {
result := radium.Article{}
result.Content = string(data)
result.ContentType = "plaintext"
result.Title = query.Text
result.Attribs = query.Attribs

return []radium.Article{result}
}

func makeRequest(ctx context.Context, query radium.Query) (*http.Request, error) {
pu, err := url.Parse(cheatShURL)
if err != nil {
return nil, err
}
queryParams := pu.Query()
queryStr := url.PathEscape(strings.Replace(strings.TrimSpace(query.Text), " ", "+", -1))

if lang, found := query.Attribs["language"]; found {
appendPath(pu, url.PathEscape(lang), queryStr)
} else {
appendPath(pu, queryStr)
}

if _, found := query.Attribs["color"]; !found {
queryParams.Set("T", "")
}

pu.RawQuery = queryParams.Encode()
req, err := http.NewRequest(http.MethodGet, pu.String(), nil)
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", "curl/7.54.0")
req.WithContext(ctx)

return req, nil
}

func isTrue(s string) bool {
switch strings.TrimSpace(strings.ToLower(s)) {
case "yes", "y", "yea", "t", "true":
return true
default:
return false
}
}

func appendPath(pu *url.URL, segs ...string) {
segs = append(segs, pu.Path)
p := filepath.Join(segs...)
pu.Path = p
}
41 changes: 41 additions & 0 deletions sources/cheatsh/tranformers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package cheatsh

import (
"regexp"

"github.com/shivylp/radium"
)

var (
langQuery = regexp.MustCompile("(.*) in (\\w+)")
languages = []string{
"go",
"golang",
"java",
"python",
"lua",
"c",
"c++",
"cpp",
"ruby",
"rails",
}
)

func transformLanguageQuery(query *radium.Query) {
matches := langQuery.FindAllStringSubmatch(query.Text, -1)
if len(matches) >= 1 && contains(languages, matches[0][2]) {
query.Text = matches[0][1]
query.Attribs["language"] = matches[0][2]
}
}

func contains(strs []string, str string) bool {
for _, s := range strs {
if s == str {
return true
}
}

return false
}

0 comments on commit 1f144fe

Please sign in to comment.