Skip to content

Commit 9ef0faf

Browse files
authored
Merge pull request #32 from kartikeysemwal/exportFeatureV1
Enhance Export Functionality: Add JSON and CSV Support (Fixes #27)
2 parents 5b7dce2 + b9b9c09 commit 9ef0faf

File tree

6 files changed

+180
-3
lines changed

6 files changed

+180
-3
lines changed

cmd/enola/enola.go

+21-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ import (
88
"github.com/spf13/cobra"
99
)
1010

11+
type cmdOptions struct {
12+
username string
13+
site string
14+
outputPath string
15+
}
16+
1117
var rootCmd = &cobra.Command{
1218
Use: "enola {username}",
1319
Short: "A command-line tool to find username on websites",
@@ -25,7 +31,15 @@ func validateArgs(cmd *cobra.Command, args []string) error {
2531
func runCommand(cmd *cobra.Command, args []string) {
2632
username := args[0]
2733
siteFlag := cmd.Flag("site")
28-
findAndShowResult(username, siteFlag.Value.String())
34+
outputPath := cmd.Flag("output")
35+
36+
options := cmdOptions{
37+
username: username,
38+
site: siteFlag.Value.String(),
39+
outputPath: outputPath.Value.String(),
40+
}
41+
42+
findAndShowResult(options)
2943
}
3044

3145
func main() {
@@ -46,4 +60,10 @@ func init() {
4660
"",
4761
"to only search an specific site",
4862
)
63+
rootCmd.Flags().StringP(
64+
"output",
65+
"o",
66+
"",
67+
"output path, supports json and csv, eg: C:\\test\\test.json",
68+
)
4969
}

cmd/enola/find.go

+38-2
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,19 @@ import (
88
"github.com/charmbracelet/bubbles/list"
99
tea "github.com/charmbracelet/bubbletea"
1010
"github.com/theyahya/enola"
11+
"github.com/theyahya/enola/cmd/exporter"
1112
)
1213

1314
type responseMsg enola.Result
1415

15-
func findAndShowResult(username, site string) {
16+
func findAndShowResult(options cmdOptions) {
1617
ctx := context.Background()
1718
sh, err := enola.New(ctx)
1819
if err != nil {
1920
panic(err)
2021
}
2122

22-
resChan, err := sh.SetSite(site).Check(username)
23+
resChan, err := sh.SetSite(options.site).Check(options.username)
2324
if err != nil {
2425
fmt.Println("Error running program: ", err)
2526
os.Exit(1)
@@ -42,4 +43,39 @@ func findAndShowResult(username, site string) {
4243
fmt.Println("Error running program: ", err)
4344
os.Exit(1)
4445
}
46+
47+
defer func() {
48+
if options.outputPath != "" {
49+
exportType := exporter.CheckExportType(options.outputPath)
50+
51+
var writer exporter.Writer = nil
52+
if exporter.JSON == exportType {
53+
writer = exporter.JsonWriter{
54+
OutputPath: options.outputPath,
55+
Items: prepareItemsForExport(m.list.Items()),
56+
}
57+
} else if exporter.CSV == exportType {
58+
writer = exporter.CsvWriter{
59+
OutputPath: options.outputPath,
60+
Items: prepareItemsForExport(m.list.Items()),
61+
}
62+
}
63+
64+
if writer != nil {
65+
writer.Write()
66+
}
67+
}
68+
}()
69+
}
70+
71+
func prepareItemsForExport(items []list.Item) []exporter.Item {
72+
var ret []exporter.Item
73+
74+
for _, value := range items {
75+
if itemValue, ok := value.(item); ok {
76+
ret = append(ret, exporter.Item{Title: itemValue.title, URL: itemValue.desc, Found: itemValue.found})
77+
}
78+
}
79+
80+
return ret
4581
}

cmd/exporter/csvWriter.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package exporter
2+
3+
import (
4+
"encoding/csv"
5+
"fmt"
6+
"strconv"
7+
)
8+
9+
type CsvWriter struct {
10+
OutputPath string
11+
Items []Item
12+
}
13+
14+
func (writer CsvWriter) Write() {
15+
file, err := OpenOrCreateFile(writer.OutputPath)
16+
if err != nil {
17+
return
18+
}
19+
defer file.Close()
20+
21+
csvWriter := csv.NewWriter(file)
22+
defer csvWriter.Flush()
23+
24+
err = csvWriter.Write([]string{"title", "url", "found"})
25+
if err != nil {
26+
fmt.Println("Error while saving content to csv file")
27+
return
28+
}
29+
30+
for _, item := range writer.Items {
31+
row := []string{item.Title, item.URL, strconv.FormatBool(item.Found)}
32+
err = csvWriter.Write(row)
33+
if err != nil {
34+
fmt.Println("Error while saving content to csv file")
35+
return
36+
}
37+
}
38+
}

cmd/exporter/jsonWriter.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package exporter
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
)
7+
8+
type JsonWriter struct {
9+
OutputPath string
10+
Items []Item
11+
}
12+
13+
func (writer JsonWriter) Write() {
14+
file, err := OpenOrCreateFile(writer.OutputPath)
15+
if err != nil {
16+
return
17+
}
18+
defer file.Close()
19+
20+
encoder := json.NewEncoder(file)
21+
encoder.SetIndent("", " ")
22+
23+
if err := encoder.Encode(writer.Items); err != nil {
24+
fmt.Println("Error while saving items to JSON file", err)
25+
}
26+
}

cmd/exporter/utils.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package exporter
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"path/filepath"
7+
"strings"
8+
)
9+
10+
func OpenOrCreateFile(filename string) (*os.File, error) {
11+
dir := filepath.Dir(filename)
12+
// 0755 permissions: the owner can read, write, and execute, everyone else can only read and execute.
13+
err := os.MkdirAll(dir, 0755)
14+
15+
if err != nil {
16+
fmt.Println("Error creating directory:", err)
17+
return nil, err
18+
}
19+
20+
// Open the file with read and write permissions
21+
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0644)
22+
if err != nil {
23+
fmt.Println(err)
24+
return nil, err
25+
}
26+
return file, nil
27+
}
28+
29+
func CheckExportType(filename string) ExportType {
30+
lowerFileName := strings.ToLower(filename)
31+
if strings.HasSuffix(strings.ToLower(lowerFileName), string(JSON)) {
32+
return JSON
33+
} else if strings.HasSuffix(strings.ToLower(lowerFileName), string(CSV)) {
34+
return CSV
35+
}
36+
37+
return NOTSUPPORTED
38+
}

cmd/exporter/writer.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package exporter
2+
3+
type ExportType string
4+
5+
const (
6+
JSON ExportType = "json"
7+
CSV ExportType = "csv"
8+
NOTSUPPORTED ExportType = "notsupported"
9+
)
10+
11+
type Item struct {
12+
Title string `json:"title"`
13+
URL string `json:"url"`
14+
Found bool `json:"found"`
15+
}
16+
17+
type Writer interface {
18+
Write()
19+
}

0 commit comments

Comments
 (0)