-
-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
747 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Package base defines shared basic pieces of the slackdump command. | ||
// | ||
// The command subsystem is based on golang's `go` command implementation, which | ||
// is BSD-licensed: | ||
// | ||
// Copyright 2017 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
package base | ||
|
||
import ( | ||
"context" | ||
"flag" | ||
) | ||
|
||
// A Command is an implementation of a slackdump command. | ||
type Command struct { | ||
// Run runs the command. | ||
// The args are the arguments after the command name. | ||
Run func(ctx context.Context, cmd *Command, args []string) | ||
|
||
// UsageLine is the one-line usage message. | ||
UsageLine string | ||
|
||
// Short is the short description shown in the 'go help' output. | ||
Short string | ||
|
||
// Long is the long message shown in the 'go help <this-command>' output. | ||
Long string | ||
|
||
// Flag is a set of flags specific to this command. | ||
Flag flag.FlagSet | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package dump |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package export |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package list |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
package v1 | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/AlecAivazis/survey/v2" | ||
|
||
"github.com/rusq/slackdump/v2/export" | ||
"github.com/rusq/slackdump/v2/internal/app" | ||
"github.com/rusq/slackdump/v2/internal/app/ui" | ||
"github.com/rusq/slackdump/v2/internal/structures" | ||
) | ||
|
||
var errExit = errors.New("exit") | ||
|
||
func Interactive(p *params) error { | ||
mode := &survey.Select{ | ||
Message: "What would you like to do?", | ||
Options: []string{"Dump", "Export", "List", "Exit"}, | ||
Description: func(value string, index int) string { | ||
descr := []string{ | ||
"save a list of conversations", | ||
"save the workspace or conversations in Slack Export format", | ||
"list conversations or users on the screen", | ||
"exit Slackdump and return to OS", | ||
} | ||
return descr[index] | ||
}, | ||
} | ||
var resp string | ||
if err := survey.AskOne(mode, &resp); err != nil { | ||
return err | ||
} | ||
var err error | ||
switch resp { | ||
case "Exit": | ||
err = errExit | ||
case "Dump": | ||
err = surveyDump(p) | ||
case "Export": | ||
err = surveyExport(p) | ||
case "List": | ||
err = surveyList(p) | ||
} | ||
return err | ||
} | ||
|
||
func surveyList(p *params) error { | ||
qs := []*survey.Question{ | ||
{ | ||
Name: "entity", | ||
Validate: survey.Required, | ||
Prompt: &survey.Select{ | ||
Message: "List: ", | ||
Options: []string{"Conversations", "Users"}, | ||
Description: func(value string, index int) string { | ||
return "List Slack " + value | ||
}, | ||
}, | ||
}, | ||
{ | ||
Name: "format", | ||
Validate: survey.Required, | ||
Prompt: &survey.Select{ | ||
Message: "Report format: ", | ||
Options: []string{app.OutputTypeText, app.OutputTypeJSON}, | ||
Description: func(value string, index int) string { | ||
return "produce output in " + value + " format" | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
mode := struct { | ||
Entity string | ||
Format string | ||
}{} | ||
|
||
var err error | ||
if err = survey.Ask(qs, &mode); err != nil { | ||
return err | ||
} | ||
|
||
switch mode.Entity { | ||
case "Conversations": | ||
p.appCfg.ListFlags.Channels = true | ||
case "Users": | ||
p.appCfg.ListFlags.Users = true | ||
} | ||
p.appCfg.Output.Format = mode.Format | ||
p.appCfg.Output.Filename, err = questOutputFile() | ||
return err | ||
} | ||
|
||
func surveyExport(p *params) error { | ||
var err error | ||
|
||
p.appCfg.ExportType, err = questExportType() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
p.appCfg.ExportName, err = ui.StringRequire( | ||
"Output directory or ZIP file: ", | ||
"Enter the output directory or ZIP file name. Add \".zip\" extension to save to a zip file.\nFor Mattermost, zip file is recommended.", | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
p.appCfg.Input.List, err = questConversationList("Conversations to export (leave empty for ALL): ") | ||
if err != nil { | ||
return err | ||
} | ||
p.appCfg.Options.DumpFiles, err = ui.Confirm("Export files?", true) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func questExportType() (export.ExportType, error) { | ||
mode := &survey.Select{ | ||
Message: "Export type: ", | ||
Options: []string{export.TMattermost.String(), export.TStandard.String()}, | ||
Description: func(value string, index int) string { | ||
descr := []string{ | ||
"Mattermost bulk upload compatible export (see doc)", | ||
"Standard export format", | ||
} | ||
return descr[index] | ||
}, | ||
} | ||
var resp string | ||
if err := survey.AskOne(mode, &resp); err != nil { | ||
return 0, err | ||
} | ||
var t export.ExportType | ||
t.Set(resp) | ||
return t, nil | ||
} | ||
|
||
func surveyDump(p *params) error { | ||
var err error | ||
p.appCfg.Input.List, err = questConversationList("Enter conversations to dump: ") | ||
return err | ||
} | ||
|
||
// questConversationList enquires the channel list. | ||
func questConversationList(msg string) (*structures.EntityList, error) { | ||
for { | ||
chanStr, err := ui.String( | ||
msg, | ||
"Enter whitespace separated conversation IDs or URLs to export.\n"+ | ||
" - prefix with ^ (caret) to exclude the converation\n"+ | ||
" - prefix with @ to read the list of converations from the file.\n\n"+ | ||
"For more details, see https://github.com/rusq/slackdump/blob/master/doc/usage-export.rst#providing-the-list-in-a-file", | ||
) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if chanStr == "" { | ||
return new(structures.EntityList), nil | ||
} | ||
if el, err := structures.MakeEntityList(strings.Split(chanStr, " ")); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
return el, nil | ||
} | ||
} | ||
} | ||
|
||
// questOutputFile prints the output file question. | ||
func questOutputFile() (string, error) { | ||
var q = &survey.Input{ | ||
Message: "Output file name (if empty - screen output): ", | ||
Suggest: func(partname string) []string { | ||
// thanks to AlecAivazis for great example of this. | ||
files, _ := filepath.Glob(partname + "*") | ||
return files | ||
}, | ||
Help: "Enter the filename to save the data to. Leave empty to print the results on the screen.", | ||
} | ||
|
||
var ( | ||
output string | ||
) | ||
for { | ||
if err := survey.AskOne(q, &output); err != nil { | ||
return "", err | ||
} | ||
if _, err := os.Stat(output); err != nil { | ||
break | ||
} | ||
overwrite, err := ui.Confirm(fmt.Sprintf("File %q exists. Overwrite?", output), false) | ||
if err != nil { | ||
return "", err | ||
} | ||
if overwrite { | ||
break | ||
} | ||
} | ||
if output == "" { | ||
output = "-" | ||
} | ||
return output, nil | ||
} |
Oops, something went wrong.