Skip to content

Commit

Permalink
commit progress
Browse files Browse the repository at this point in the history
  • Loading branch information
rusq committed Aug 29, 2022
1 parent 8b4f165 commit 895dcc1
Show file tree
Hide file tree
Showing 8 changed files with 747 additions and 5 deletions.
33 changes: 33 additions & 0 deletions cmd/slackdump/internal/base/base.go
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
}
1 change: 1 addition & 0 deletions cmd/slackdump/internal/dump/dump.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dump
1 change: 1 addition & 0 deletions cmd/slackdump/internal/export/export.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package export
1 change: 1 addition & 0 deletions cmd/slackdump/internal/list/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package list
210 changes: 210 additions & 0 deletions cmd/slackdump/internal/v1/interactive.go
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
}
Loading

0 comments on commit 895dcc1

Please sign in to comment.