Merge pull request #53 from 178inaba/xsearch

Fix XSearch
pull/55/head
mattn 2017-05-08 09:17:04 +09:00 committed by GitHub
commit b88b19a217
7 changed files with 132 additions and 25 deletions

View File

@ -28,6 +28,7 @@ COMMANDS:
delete delete status delete delete status
init initialize profile init initialize profile
mikami search mikami mikami search mikami
xsearch cross search
help, h Shows a list of commands or help for one command help, h Shows a list of commands or help for one command
GLOBAL OPTIONS: GLOBAL OPTIONS:

View File

@ -1,26 +1,9 @@
package main package main
import ( import (
"fmt"
"github.com/PuerkitoBio/goquery"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
func cmdMikami(c *cli.Context) error { func cmdMikami(c *cli.Context) error {
doc, err := goquery.NewDocument("http://mastodonsearch.jp/cross/?q=三上") return xSearch(c.App.Metadata["xsearch_url"].(string), "三上", c.App.Writer)
if err != nil {
return err
}
doc.Find(".post").Each(func(n int, elem *goquery.Selection) {
href, ok := elem.Find(".mst_content a").Attr("href")
if !ok {
return
}
text := elem.Find(".mst_content p").Text()
fmt.Println(href)
fmt.Println(text)
fmt.Println()
})
return nil
} }

View File

@ -0,0 +1,41 @@
package main
import (
"bytes"
"fmt"
"net/http"
"strings"
"testing"
"github.com/urfave/cli"
)
func TestCmdMikami(t *testing.T) {
ok := false
buf := bytes.NewBuffer(nil)
testWithServer(
func(w http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("q") == "三上" {
ok = true
fmt.Fprintln(w, `<div class="post"><div class="mst_content"><a href="http://example.com/@test/1"><p>三上</p></a></div></div>`)
}
},
func(app *cli.App) {
app.Writer = buf
err := app.Run([]string{"mstdn", "mikami"})
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
},
)
if !ok {
t.Fatal("should be search Mikami")
}
result := buf.String()
if !strings.Contains(result, "http://example.com/@test/1") {
t.Fatalf("%q should be contained in output of search: %s", "http://example.com/@test/1", result)
}
if !strings.Contains(result, "三上") {
t.Fatalf("%q should be contained in output of search: %s", "三上", result)
}
}

View File

@ -30,6 +30,7 @@ func testWithServer(h http.HandlerFunc, testFuncs ...func(*cli.App)) string {
"config": &mastodon.Config{ "config": &mastodon.Config{
Server: "https://example.com", Server: "https://example.com",
}, },
"xsearch_url": ts.URL,
} }
for _, f := range testFuncs { for _, f := range testFuncs {

View File

@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"io"
"net/url" "net/url"
"github.com/PuerkitoBio/goquery" "github.com/PuerkitoBio/goquery"
@ -9,12 +10,16 @@ import (
) )
func cmdXSearch(c *cli.Context) error { func cmdXSearch(c *cli.Context) error {
u, err := url.Parse("http://mastodonsearch.jp/cross/") return xSearch(c.App.Metadata["xsearch_url"].(string), c.Args().First(), c.App.Writer)
}
func xSearch(xsearchRawurl, query string, w io.Writer) error {
u, err := url.Parse(xsearchRawurl)
if err != nil { if err != nil {
return err return err
} }
params := url.Values{} params := url.Values{}
params.Set("q", c.Args().First()) params.Set("q", query)
u.RawQuery = params.Encode() u.RawQuery = params.Encode()
doc, err := goquery.NewDocument(u.String()) doc, err := goquery.NewDocument(u.String())
if err != nil { if err != nil {
@ -26,9 +31,8 @@ func cmdXSearch(c *cli.Context) error {
return return
} }
text := elem.Find(".mst_content p").Text() text := elem.Find(".mst_content p").Text()
fmt.Println(href) fmt.Fprintf(w, "%s\n", href)
fmt.Println(text) fmt.Fprintf(w, "%s\n\n", text)
fmt.Println()
}) })
return nil return nil
} }

View File

@ -0,0 +1,76 @@
package main
import (
"bytes"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/urfave/cli"
)
func TestCmdXSearch(t *testing.T) {
testWithServer(
func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `<div class="post"><div class="mst_content"><a href="http://example.com/@test/1"><p>test status</p></a></div></div>`)
},
func(app *cli.App) {
err := app.Run([]string{"mstdn", "xsearch", "test"})
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
},
)
}
func TestXSearch(t *testing.T) {
canErr := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if canErr {
canErr = false
http.Error(w, http.StatusText(http.StatusInternalServerError), 9999)
return
} else if r.URL.Query().Get("q") == "empty" {
fmt.Fprintln(w, `<div class="post"><div class="mst_content"><a><p>test status</p></a></div></div>`)
return
}
fmt.Fprintln(w, `<div class="post"><div class="mst_content"><a href="http://example.com/@test/1"><p>test status</p></a></div></div>`)
}))
defer ts.Close()
err := xSearch(":", "", nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
err = xSearch(ts.URL, "", nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
buf := bytes.NewBuffer(nil)
err = xSearch(ts.URL, "empty", buf)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
result := buf.String()
if result != "" {
t.Fatalf("the search result should be empty: %s", result)
}
buf = bytes.NewBuffer(nil)
err = xSearch(ts.URL, "test", buf)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
result = buf.String()
if !strings.Contains(result, "http://example.com/@test/1") {
t.Fatalf("%q should be contained in output of search: %s", "http://example.com/@test/1", result)
}
if !strings.Contains(result, "test status") {
t.Fatalf("%q should be contained in output of search: %s", "test status", result)
}
}

View File

@ -361,8 +361,9 @@ func run() int {
client := mastodon.NewClient(config) client := mastodon.NewClient(config)
app.Metadata = map[string]interface{}{ app.Metadata = map[string]interface{}{
"client": client, "client": client,
"config": config, "config": config,
"xsearch_url": "http://mastodonsearch.jp/cross/",
} }
if config.AccessToken == "" { if config.AccessToken == "" {
return authenticate(client, config, file) return authenticate(client, config, file)