mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2026-02-04 08:18:34 +00:00
feat(GODT-3121): added options to kb-tester CLI tool.
This commit is contained in:
@ -4,8 +4,7 @@
|
|||||||
"url": "https://proton.me/support/automatically-start-bridge",
|
"url": "https://proton.me/support/automatically-start-bridge",
|
||||||
"title": "Automatically start Bridge",
|
"title": "Automatically start Bridge",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"start",
|
"automatic",
|
||||||
"automatically",
|
|
||||||
"login",
|
"login",
|
||||||
"start",
|
"start",
|
||||||
"boot"
|
"boot"
|
||||||
@ -53,7 +52,8 @@
|
|||||||
"title": "Proton Mail Bridge connection issues with Thunderbird, Outlook, and Apple Mail",
|
"title": "Proton Mail Bridge connection issues with Thunderbird, Outlook, and Apple Mail",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"connect",
|
"connect",
|
||||||
"error",
|
"SSL",
|
||||||
|
"STARTTLS",
|
||||||
"client",
|
"client",
|
||||||
"program",
|
"program",
|
||||||
"Outlook",
|
"Outlook",
|
||||||
@ -68,7 +68,8 @@
|
|||||||
"keywords": [
|
"keywords": [
|
||||||
"pgp",
|
"pgp",
|
||||||
"gpg",
|
"gpg",
|
||||||
"encrypt"
|
"encrypt",
|
||||||
|
"crypto"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -205,7 +206,6 @@
|
|||||||
"Outlook",
|
"Outlook",
|
||||||
"configure",
|
"configure",
|
||||||
"setup",
|
"setup",
|
||||||
"program",
|
|
||||||
"application",
|
"application",
|
||||||
"setup",
|
"setup",
|
||||||
"IMAP",
|
"IMAP",
|
||||||
|
|||||||
@ -52,14 +52,20 @@ func GetArticleList() (ArticleList, error) {
|
|||||||
return articles, err
|
return articles, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSuggestions return a list of up to 3 suggestions for KB articles matching the given user input.
|
// GetSuggestions returns a list of up to 3 suggestions for the built-in list of KB articles matching the given user input.
|
||||||
func GetSuggestions(userInput string) (ArticleList, error) {
|
func GetSuggestions(userInput string) (ArticleList, error) {
|
||||||
userInput = strings.ToUpper(userInput)
|
|
||||||
articles, err := GetArticleList()
|
articles, err := GetArticleList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ArticleList{}, err
|
return ArticleList{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return GetSuggestionsFromArticleList(userInput, articles)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSuggestionsFromArticleList returns a list of up to 3 suggestions for the given list of KB articles matching the given user input.
|
||||||
|
func GetSuggestionsFromArticleList(userInput string, articles ArticleList) (ArticleList, error) {
|
||||||
|
userInput = strings.ToUpper(userInput)
|
||||||
|
|
||||||
for _, article := range articles {
|
for _, article := range articles {
|
||||||
for _, keyword := range article.Keywords {
|
for _, keyword := range article.Keywords {
|
||||||
if strings.Contains(userInput, strings.ToUpper(keyword)) {
|
if strings.Contains(userInput, strings.ToUpper(keyword)) {
|
||||||
@ -78,7 +84,7 @@ func GetSuggestions(userInput string) (ArticleList, error) {
|
|||||||
return articles, nil
|
return articles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetArticleIndex retrieve the index of an article from its url. if the article is not found, ErrArticleNotFound is returned.
|
// GetArticleIndex retrieves the index of an article from its url. if the article is not found, ErrArticleNotFound is returned.
|
||||||
func GetArticleIndex(url string) (uint64, error) {
|
func GetArticleIndex(url string) (uint64, error) {
|
||||||
articles, err := GetArticleList()
|
articles, err := GetArticleList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -18,7 +18,6 @@
|
|||||||
package kb
|
package kb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -42,16 +41,39 @@ func Test_ArticleList(t *testing.T) {
|
|||||||
func Test_GetSuggestions(t *testing.T) {
|
func Test_GetSuggestions(t *testing.T) {
|
||||||
suggestions, err := GetSuggestions("Thunderbird is not working, error during password")
|
suggestions, err := GetSuggestions("Thunderbird is not working, error during password")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, len(suggestions) <= 3)
|
count := len(suggestions)
|
||||||
for _, article := range suggestions {
|
require.True(t, (count > 0) && (count <= 3))
|
||||||
fmt.Printf("Score: %v - %#v\n", article.Score, article.Title)
|
|
||||||
}
|
|
||||||
|
|
||||||
suggestions, err = GetSuggestions("Supercalifragilisticexpialidocious Sesquipedalian Worcestershire")
|
suggestions, err = GetSuggestions("Supercalifragilisticexpialidocious Sesquipedalian Worcestershire")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Empty(t, suggestions)
|
require.Empty(t, suggestions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_GetSuggestionsFromArticleList(t *testing.T) {
|
||||||
|
articleList := ArticleList{}
|
||||||
|
suggestions, err := GetSuggestionsFromArticleList("Thunderbird", articleList)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Empty(t, suggestions)
|
||||||
|
|
||||||
|
articleList = ArticleList{
|
||||||
|
&Article{
|
||||||
|
Index: 0,
|
||||||
|
URL: "https://proton.me",
|
||||||
|
Title: "Proton home page",
|
||||||
|
Keywords: []string{"proton"},
|
||||||
|
},
|
||||||
|
&Article{
|
||||||
|
Index: 1,
|
||||||
|
URL: "https://mozilla.org",
|
||||||
|
Title: "Mozilla home page",
|
||||||
|
Keywords: []string{"mozilla"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
suggestions, err = GetSuggestionsFromArticleList("PRoToN", articleList)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, suggestions, 1)
|
||||||
|
require.Equal(t, suggestions[0].URL, "https://proton.me")
|
||||||
|
}
|
||||||
|
|
||||||
func Test_GetArticleIndex(t *testing.T) {
|
func Test_GetArticleIndex(t *testing.T) {
|
||||||
index1, err := GetArticleIndex("https://proton.me/support/bridge-for-linux")
|
index1, err := GetArticleIndex("https://proton.me/support/bridge-for-linux")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@ -18,40 +18,120 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/ProtonMail/proton-bridge/v3/internal/kb"
|
"github.com/ProtonMail/proton-bridge/v3/internal/kb"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkErrors(err error) {
|
const flagArticles = "articles"
|
||||||
if err != nil {
|
const flagInput = "input"
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
os.Exit(1)
|
func main() {
|
||||||
|
app := &cli.App{
|
||||||
|
Name: "kb-suggester",
|
||||||
|
Usage: "test bridge KB article suggester",
|
||||||
|
HideHelpCommand: true,
|
||||||
|
ArgsUsage: "",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: flagArticles,
|
||||||
|
Aliases: []string{"a"},
|
||||||
|
Usage: "use `articles.json` as the JSON article list",
|
||||||
|
TakesFile: true,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: flagInput,
|
||||||
|
Aliases: []string{"i"},
|
||||||
|
Usage: "read user input from the `userInput` file",
|
||||||
|
TakesFile: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: run,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := app.Run(os.Args); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func getUserInput(ctx *cli.Context) (string, error) {
|
||||||
fi, err := os.Stdin.Stat()
|
inputFile := ctx.String(flagInput)
|
||||||
checkErrors(err)
|
var bytes []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
if (fi.Mode() & os.ModeNamedPipe) == 0 {
|
if len(inputFile) == 0 {
|
||||||
fmt.Println("Type your input, Ctrl+D to finish: ")
|
var fi os.FileInfo
|
||||||
|
if fi, err = os.Stdin.Stat(); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fi.Mode() & os.ModeNamedPipe) == 0 {
|
||||||
|
fmt.Println("Type your input, Ctrl+D to finish: ")
|
||||||
|
}
|
||||||
|
bytes, err = io.ReadAll(os.Stdin)
|
||||||
|
} else {
|
||||||
|
bytes, err = os.ReadFile(filepath.Clean(inputFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes, err := io.ReadAll(os.Stdin)
|
if err != nil {
|
||||||
checkErrors(err)
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
suggestions, err := kb.GetSuggestions(string(bytes))
|
return string(bytes), nil
|
||||||
checkErrors(err)
|
}
|
||||||
|
|
||||||
|
func getArticleList(ctx *cli.Context) (kb.ArticleList, error) {
|
||||||
|
articleFile := ctx.String(flagArticles)
|
||||||
|
if len(articleFile) == 0 {
|
||||||
|
return kb.GetArticleList()
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err := os.ReadFile(filepath.Clean(articleFile))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result kb.ArticleList
|
||||||
|
err = json.Unmarshal(bytes, &result)
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func run(ctx *cli.Context) error {
|
||||||
|
if ctx.Args().Len() > 0 {
|
||||||
|
_ = cli.ShowAppHelp(ctx)
|
||||||
|
return errors.New("command accept no argument")
|
||||||
|
}
|
||||||
|
|
||||||
|
articles, err := getArticleList(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
userInput, err := getUserInput(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
suggestions, err := kb.GetSuggestionsFromArticleList(userInput, articles)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if len(suggestions) == 0 {
|
if len(suggestions) == 0 {
|
||||||
fmt.Println("No suggestions found")
|
fmt.Println("No suggestions found")
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, suggestion := range suggestions {
|
for _, suggestion := range suggestions {
|
||||||
fmt.Printf("Score %v: %v (%v)\n", suggestion.Score, suggestion.Title, suggestion.URL)
|
fmt.Printf("Score %v: %v (%v)\n", suggestion.Score, suggestion.Title, suggestion.URL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user