From 785774e31d9628ee6ab461736e6972929d5b1713 Mon Sep 17 00:00:00 2001 From: sheepla <62412884+sheepla@users.noreply.github.com> Date: Sat, 26 Mar 2022 14:55:09 +0900 Subject: [PATCH] =?UTF-8?q?=E8=A8=98=E4=BA=8B=E3=81=AE=E3=83=97=E3=83=AC?= =?UTF-8?q?=E3=83=93=E3=83=A5=E3=83=BC=E6=A9=9F=E8=83=BD=E3=82=92=E5=AE=9F?= =?UTF-8?q?=E8=A3=85=20(#2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Implement `--preview` option * Fix * Update README.md * Fix README.md --- README.md | 69 ++++++++++++++++++++++++++++++++++++++++-------- client/client.go | 32 ++++++++++++++++++++-- go.mod | 14 +++++++++- go.sum | 42 ++++++++++++++++++++++++++++- main.go | 26 +++++++++++++----- 5 files changed, 161 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 3adc42a..60e77ff 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,11 @@
-A command line [Qiita](https://qiita.com) searcher with fuzzyfinder UI +[Qiita](https://qiita.com)の記事を検索・ターミナル上でプレビューできるコマンドラインツール
-## Usage +## 使い方 ``` Usage: @@ -39,22 +39,69 @@ Help Options: -h, --help Show this help message ``` -## Installation +1. 引数に検索したいキーワードを指定してコマンドを実行します。 +1. 検索結果をfuzzyfinderで絞り込みます。`Ctrl-N`, `Ctrl-P` または `Ctrl-J`, `Ctrl-K` でフォーカスを移動します。 `Tab`キーで選択し `Enter` キーで確定します。 +1. 選択した記事のURLが出力されます。次のオプションを指定することで、選択した記事をブラウザで開いたりターミナル上でプレビューしたりすることができます。 -### Build from Source +### ブラウザで記事のページを開く -Clone this repository then run `go install`. -Requires Go, testing on `v1.17.8 linux/amd64` +`-o`, `--open`オプションを付けるとデフォルトのブラウザが起動し、選択した記事のページが開きます。 -### Download Executable Binary +### 記事をプレビューする -> [Latest Release](https://github.com/sheepla/qiitaz/releases/latest) +`-p`, `--preview` オプションを付けると、ターミナル上で記事をプレビューすることができます。 +lessなどのページャを使うと読みやすいです。 + +```bash +qiitaz -p QUERY... | less -R +``` + +### 高度な検索 + +クエリ引数に次のオプションや演算子を指定することで、条件を詳細に指定して検索することができます。 + +``` +qiitaz title:Go created:\>2022-03-01 +``` + +|オプション |説明 | +|--------------------|----------------------------------| +|`title:{{string}}` |タイトルにそのキーワードが含まれる| +|`body:{{string}}` |本文にそのキーワードが含まれる | +|`code:{{string}}` |コードにそのキーワードが含まれる | +|`tag:{{string}}` |記事に付けられているタグ | +|`-tag:{{string}}` |除外するタグ | +|`user:{{string}}` |ユーザー名 | +|`stocks:\>{{int}}` |ストック数 | +|`created:\>{{date}}`|作成日がその日以降 | +|`updated:\>{{date}}`|更新日がその日以降 | -## LICENSE -[MIT](./LICENSE) +|演算子 |説明 | +|----------------------|------| +|`{{条件}} OR {{条件}}`|OR条件| + +また、`-s`, `--sort` オプションを指定することで、ソート条件を変更することができます。 + +**例**: `qiitaz -s like Go` + +|値 |説明 | +|---------|------------------| +|`rel` |関連度順 | +|`like` |LGTM数の多い順 | +|`stock` |ストック数の多い順| +|`created`|作成日順 | + +## インストール + +リリースページから実行可能なバイナリをダウンロード可能です。 + +> [Latest Release](https://github.com/sheepla/qiitaz/releases/latest) + +ソースからビルドする場合は、このリポジトリをクローンして `go install` を実行してください。 +`v1.17.8 linux/amd64`で開発しています。 -## Related Projects +## 関連 - [sheepla/fzwiki](https://github.com/sheepla/fzwiki) - [sheepla/fzenn](https://github.com/sheepla/fzenn) diff --git a/client/client.go b/client/client.go index bd6e22a..b585c2d 100644 --- a/client/client.go +++ b/client/client.go @@ -2,10 +2,12 @@ package client import ( "fmt" + "io" "net/http" "net/url" "github.com/PuerkitoBio/goquery" + "github.com/charmbracelet/glamour" ) type Result struct { @@ -33,7 +35,7 @@ func (s SortBy) varidate() bool { } } -func NewURL(query string, sortby SortBy) (string, error) { +func NewSearchURL(query string, sortby SortBy) (string, error) { if !sortby.varidate() { return "", fmt.Errorf("invalid sort key: %s", sortby) } @@ -50,7 +52,7 @@ func NewURL(query string, sortby SortBy) (string, error) { return u.String(), nil } -func Get(url string) ([]Result, error) { +func Search(url string) ([]Result, error) { res, err := http.Get(url) if err != nil { return nil, err @@ -79,3 +81,29 @@ func Get(url string) ([]Result, error) { return results, err } + +func NewPageURL(path string) string { + u := &url.URL{ + Scheme: "https", + Host: "qiita.com", + Path: path, + } + return u.String() +} + +func Preview(url, style string) (*string, error) { + res, err := http.Get(url) + if err != nil { + return nil, err + } + defer res.Body.Close() + body, err := io.ReadAll(res.Body) + if err != nil { + return nil, err + } + view, err := glamour.Render(string(body), style) + if err != nil { + return nil, err + } + return &view, nil +} diff --git a/go.mod b/go.mod index 0ec532f..f72c1da 100644 --- a/go.mod +++ b/go.mod @@ -4,20 +4,32 @@ go 1.17 require ( github.com/PuerkitoBio/goquery v1.8.0 + github.com/charmbracelet/glamour v0.5.0 github.com/jessevdk/go-flags v1.5.0 github.com/ktr0731/go-fuzzyfinder v0.6.0 github.com/toqueteos/webbrowser v1.2.0 ) require ( + github.com/alecthomas/chroma v0.10.0 // indirect github.com/andybalholm/cascadia v1.3.1 // indirect + github.com/aymerick/douceur v0.2.0 // indirect + github.com/dlclark/regexp2 v1.4.0 // indirect github.com/gdamore/encoding v1.0.0 // indirect github.com/gdamore/tcell/v2 v2.4.0 // indirect - github.com/lucasb-eyer/go-colorful v1.0.3 // indirect + github.com/gorilla/css v1.0.0 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.13 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/microcosm-cc/bluemonday v1.0.17 // indirect + github.com/muesli/reflow v0.3.0 // indirect + github.com/muesli/termenv v0.9.0 // indirect github.com/nsf/termbox-go v0.0.0-20201124104050-ed494de23a00 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/yuin/goldmark v1.4.4 // indirect + github.com/yuin/goldmark-emoji v1.0.1 // indirect golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 // indirect golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect diff --git a/go.sum b/go.sum index c40dba8..e5ee564 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,18 @@ github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U= github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI= +github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek= +github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s= github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/charmbracelet/glamour v0.5.0 h1:wu15ykPdB7X6chxugG/NNfDUbyyrCLV9XBalj5wdu3g= +github.com/charmbracelet/glamour v0.5.0/go.mod h1:9ZRtG19AUIzcTm7FGLGbq3D5WKQ5UyZBbQsMQN0XIqc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= +github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/tcell/v2 v2.4.0 h1:W6dxJEmaxYvhICFoTY3WrLLEXsQ11SaFnKGVEXW57KM= @@ -10,27 +21,53 @@ github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/ktr0731/go-fuzzyfinder v0.6.0 h1:lP6B3B8CjqbKGf/K5f1X5kdpxiSkCH0+9AzgA3Cm+VU= github.com/ktr0731/go-fuzzyfinder v0.6.0/go.mod h1:QrbU5RFMEFBbPZnlJBqctX6028IV8qW/yCX3DCAzi1Y= -github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= +github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/microcosm-cc/bluemonday v1.0.17 h1:Z1a//hgsQ4yjC+8zEkV8IWySkXnsxmdSY642CTFQb5Y= +github.com/microcosm-cc/bluemonday v1.0.17/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/muesli/termenv v0.9.0 h1:wnbOaGz+LUR3jNT0zOzinPnyDaCZUQRZj9GxK8eRVl8= +github.com/muesli/termenv v0.9.0/go.mod h1:R/LzAKf+suGs4IsO95y7+7DpFHO0KABgnZqtlyx2mBw= github.com/nsf/termbox-go v0.0.0-20201124104050-ed494de23a00 h1:Rl8NelBe+n7SuLbJyw13ho7CGWUt2BjGGKIoreCWQ/c= github.com/nsf/termbox-go v0.0.0-20201124104050-ed494de23a00/go.mod h1:T0cTdVuOwf7pHQNtfhnEbzHbcNyCEcVU4YPpouCbVxo= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ= github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.4 h1:zNWRjYUW32G9KirMXYHQHVNFkXvMI7LpgNW2AgYAoIs= +github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= +github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os= +github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk= golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -45,3 +82,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index bb80a6a..0ffaded 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,7 @@ type options struct { Version bool `short:"V" long:"version" description:"Show version"` Sort string `short:"s" long:"sort" description:"Sort key to search e.g. \"created\", \"like\", \"stock\", \"rel\", (default: \"rel\")" ` Open bool `short:"o" long:"open" description:"Open URL in your web browser"` + Preview bool `short:"p" long:"preview" description:"Preview page on your terminal"` } const ( @@ -37,6 +38,7 @@ const ( exitCodeErrRequest exitCodeErrFuzzyFinder exitCodeErrWebbrowser + exitCodeErrPreview ) func main() { @@ -73,13 +75,13 @@ func Main(cliArgs []string) exitCode { if opts.Sort != "" { sortby = opts.Sort } - url, err := client.NewURL(strings.Join(args, " "), client.SortBy(sortby)) + url, err := client.NewSearchURL(strings.Join(args, " "), client.SortBy(sortby)) if err != nil { log.Println(err) return exitCodeErrArgs } - result, err := client.Get(url) + result, err := client.Search(url) if err != nil { log.Println(err) return exitCodeErrRequest @@ -91,15 +93,25 @@ func Main(cliArgs []string) exitCode { return exitCodeErrFuzzyFinder } - for _, idx := range choices { - url := path.Join(baseURL, result[idx].Link) - if opts.Open { + if opts.Open { + for _, idx := range choices { + url := path.Join(baseURL, result[idx].Link) if err := webbrowser.Open(url); err != nil { log.Println(err) return exitCodeErrWebbrowser } - } else { - fmt.Println(url) + } + } + + if opts.Preview { + for _, idx := range choices { + url := client.NewPageURL((result[idx].Link + ".md")) + view, err := client.Preview(url, "dark") + if err != nil { + log.Println(err) + return exitCodeErrPreview + } + fmt.Fprintf(os.Stdout, *view) } }