Skip to content

Commit

Permalink
remove redundant namer
Browse files Browse the repository at this point in the history
  • Loading branch information
rusq committed Mar 5, 2023
1 parent 9fcd8da commit b2e2da3
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 95 deletions.
76 changes: 29 additions & 47 deletions cmd/slackdump/internal/dump/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import (
"errors"
"flag"
"fmt"
"io/fs"
"os"
"path/filepath"
"runtime/trace"
"strings"
"text/template"
Expand Down Expand Up @@ -99,7 +97,7 @@ func RunDump(ctx context.Context, cmd *base.Command, args []string) error {
if opts.NameTemplate == "" {
opts.NameTemplate = nametmpl.Default
}
namer, err := newNamer(opts.NameTemplate, "json")
tmpl, err := nametmpl.New(opts.NameTemplate + ".json")
if err != nil {
base.SetExitStatus(base.SUserError)
return fmt.Errorf("file template error: %w", err)
Expand All @@ -126,14 +124,14 @@ func RunDump(ctx context.Context, cmd *base.Command, args []string) error {
DumpFiles: cfg.SlackConfig.DumpFiles,
}

if err := dumpv3(ctx, sess, tmpdir, namer, p); err != nil {
if err := dumpv3(ctx, sess, tmpdir, tmpl, p); err != nil {
base.SetExitStatus(base.SApplicationError)
return err
}
return nil
}

func dumpv3(ctx context.Context, sess *slackdump.Session, dir string, namer namer, p *fetch.Parameters) error {
func dumpv3(ctx context.Context, sess *slackdump.Session, dir string, tmpl *nametmpl.Template, p *fetch.Parameters) error {
ctx, task := trace.NewTask(ctx, "dumpv3")
defer task.End()

Expand All @@ -145,7 +143,7 @@ func dumpv3(ctx context.Context, sess *slackdump.Session, dir string, namer name

lg.Printf("using temporary directory: %s ", dir)

tf := transform.NewStandard(sess.Filesystem(), transform.WithNameFn(namer.Filename))
tf := transform.NewStandard(sess.Filesystem(), transform.WithNameFn(tmpl.Execute))
var eg errgroup.Group
for _, link := range p.List.Include {
lg.Printf("fetching %q", link)
Expand All @@ -156,29 +154,45 @@ func dumpv3(ctx context.Context, sess *slackdump.Session, dir string, namer name
if err != nil {
return err
}
lg.Printf("transforming %q", link)
st, err := state.Load(statefile)
if err != nil {
return err
}
eg.Go(func() error {
return tf.Transform(ctx, st, dir)
return convertChunks(ctx, tf, statefile, dir)
})
}
lg.Printf("waiting for all conversations to be transformed...")
lg.Printf("waiting for all conversations to finish conversion...")
if err := eg.Wait(); err != nil {
return err
}
return os.RemoveAll(dir)
}

func convertChunks(ctx context.Context, tf transform.Interface, statefile string, dir string) error {
ctx, task := trace.NewTask(ctx, "convert")
defer task.End()

lg := dlog.FromContext(ctx)

lg.Printf("converting %q", statefile)
st, err := state.Load(statefile)
if err != nil {
return err
}
if err := tf.Transform(ctx, dir, st); err != nil {
return err
}
return nil
}

func dumpv2(ctx context.Context, sess *slackdump.Session, list *structures.EntityList, namer namer) error {
func dumpv2(ctx context.Context, sess *slackdump.Session, list *structures.EntityList, t *nametmpl.Template) error {
for _, link := range list.Include {
conv, err := sess.Dump(ctx, link, opts.Oldest, opts.Latest)
if err != nil {
return err
}
if err := save(ctx, sess.Filesystem(), namer.Filename(conv), conv); err != nil {
name, err := t.Execute(conv)
if err != nil {
return err
}
if err := save(ctx, sess.Filesystem(), name, conv); err != nil {
return err
}
}
Expand Down Expand Up @@ -208,35 +222,3 @@ func HelpDump(cmd *base.Command) string {
}
return buf.String()
}

// Reconstruct reconstructs the conversation files from the temporary directory
// with state files and chunk records.
func Reconstruct(ctx context.Context, fsa fsadapter.FS, tmpdir string, namer namer) error {
_, task := trace.NewTask(ctx, "reconstruct")
defer task.End()

tf := transform.NewStandard(fsa, transform.WithNameFn(namer.Filename))

return filepath.WalkDir(tmpdir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
if path != tmpdir {
return filepath.SkipDir
}
return nil
}
if filepath.Ext(path) != ".state" {
return nil
}

st, err := state.Load(path)
if err != nil {
return fmt.Errorf("failed to load state file: %w", err)
}

dlog.Printf("reconstructing %s", st.Filename)
return tf.Transform(ctx, st, tmpdir)
})
}
32 changes: 0 additions & 32 deletions cmd/slackdump/internal/dump/namer.go

This file was deleted.

5 changes: 2 additions & 3 deletions internal/app/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package config
import (
"errors"
"fmt"
"text/template"

"github.com/rusq/slackdump/v2"
"github.com/rusq/slackdump/v2/export"
Expand Down Expand Up @@ -143,8 +142,8 @@ func (p *Params) Validate() error {
return nil
}

func (p *Params) CompileTemplates() (*template.Template, error) {
return nametmpl.Compile(p.FilenameTemplate)
func (p *Params) CompileTemplates() (*nametmpl.Template, error) {
return nametmpl.New(p.FilenameTemplate)
}

// Producer iterates over the list or reads the list from the file and calls
Expand Down
5 changes: 2 additions & 3 deletions internal/app/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"io"
"os"
"runtime/trace"
"text/template"
"time"

"github.com/rusq/fsadapter"
Expand Down Expand Up @@ -106,13 +105,13 @@ type dumpFunc func(context.Context, string, time.Time, time.Time, ...slackdump.P

// dumpOneChannel dumps just one channel specified by channelInput. If
// generateText is true, it will also generate a ID.txt text file.
func (app *dump) dumpOne(ctx context.Context, fs fsadapter.FS, filetmpl *template.Template, channelInput string, fn dumpFunc) error {
func (app *dump) dumpOne(ctx context.Context, fs fsadapter.FS, filetmpl *nametmpl.Template, channelInput string, fn dumpFunc) error {
cnv, err := fn(ctx, channelInput, time.Time(app.cfg.Oldest), time.Time(app.cfg.Latest))
if err != nil {
return err
}

filename, err := nametmpl.ExecuteTemplate(filetmpl, cnv)
filename, err := filetmpl.Execute(cnv)
if err != nil {
return err
}
Expand Down
33 changes: 30 additions & 3 deletions internal/nametmpl/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,29 @@ var tc = types.Conversation{
ThreadTS: mPartialOK,
}

type Template struct {
t *template.Template
}

func New(t string) (*Template, error) {
tmpl, err := compile(t)
if err != nil {
return nil, err
}
return &Template{tmpl}, nil
}

func NewDefault() *Template {
t, err := New(Default)
if err != nil {
panic(err)
}
return t
}

// Compile checks the template for validness and compiles it returning the
// template and an error if any.
func Compile(t string) (*template.Template, error) {
func compile(t string) (*template.Template, error) {
tmpl, err := template.New(filenameTmplName).Parse(t)
if err != nil {
return nil, err
Expand All @@ -55,10 +75,17 @@ func Compile(t string) (*template.Template, error) {
return tmpl, nil
}

func ExecuteTemplate(tmpl *template.Template, c *types.Conversation) (string, error) {
func (t *Template) Execute(c *types.Conversation) (string, error) {
var buf strings.Builder
if err := tmpl.ExecuteTemplate(&buf, filenameTmplName, c); err != nil {
if err := t.t.ExecuteTemplate(&buf, filenameTmplName, c); err != nil {
return "", err
}
return buf.String(), nil
}

func Must(s string, err error) string {
if err != nil {
panic(err)
}
return s
}
2 changes: 1 addition & 1 deletion internal/nametmpl/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestCompile(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Compile(tt.args.t)
got, err := compile(tt.args.t)
if (err != nil) != tt.wantErr {
t.Errorf("Compile() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down
43 changes: 43 additions & 0 deletions internal/transform/reconstruct.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package transform

import (
"context"
"fmt"
"io/fs"
"path/filepath"
"runtime/trace"

"github.com/rusq/dlog"
"github.com/rusq/fsadapter"
"github.com/rusq/slackdump/v2/internal/chunk/state"
)

// Reconstruct reconstructs the conversation files from the temporary directory
// with state files and chunk records.
func Reconstruct(ctx context.Context, fsa fsadapter.FS, tmpdir string, tf Interface) error {
_, task := trace.NewTask(ctx, "reconstruct")
defer task.End()

return filepath.WalkDir(tmpdir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
if path != tmpdir {
return filepath.SkipDir
}
return nil
}
if filepath.Ext(path) != ".state" {
return nil
}

st, err := state.Load(path)
if err != nil {
return fmt.Errorf("failed to load state file: %w", err)
}

dlog.Printf("reconstructing %s", st.Filename)
return tf.Transform(ctx, tmpdir, st)
})
}
16 changes: 11 additions & 5 deletions internal/transform/standard.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/rusq/slackdump/v2/internal/chunk"
"github.com/rusq/slackdump/v2/internal/chunk/state"
"github.com/rusq/slackdump/v2/internal/nametmpl"
"github.com/rusq/slackdump/v2/internal/osext"
"github.com/rusq/slackdump/v2/internal/structures/files"
"github.com/rusq/slackdump/v2/types"
Expand All @@ -22,7 +23,7 @@ type Standard struct {
// fs is the filesystem to write the transformed data to.
fs fsadapter.FS
// nameFn returns the filename for a given conversation.
nameFn func(*types.Conversation) string
nameFn func(*types.Conversation) (string, error)
// updateFileLink indicates whether the file link should be updated
// with the path to the file within the archive/directory.
updateFileLink bool
Expand All @@ -44,7 +45,7 @@ func WithUpdateFileLink(updateFileLink bool) StandardOption {

// WithNameFn allows to specify a custom function to generate the filename
// for the conversation. By default the conversation ID is used.
func WithNameFn(nameFn func(*types.Conversation) string) StandardOption {
func WithNameFn(nameFn func(*types.Conversation) (string, error)) StandardOption {
return func(s *Standard) {
s.nameFn = nameFn
}
Expand All @@ -54,9 +55,10 @@ func WithNameFn(nameFn func(*types.Conversation) string) StandardOption {
// filename for a given conversation. This is the name that the conversation
// will be written to the filesystem.
func NewStandard(fs fsadapter.FS, opts ...StandardOption) *Standard {
t := nametmpl.NewDefault()
s := &Standard{
fs: fs,
nameFn: func(c *types.Conversation) string { return c.ID + ".json" },
nameFn: t.Execute,
seenFiles: make(map[string]struct{}),
}
for _, opt := range opts {
Expand All @@ -66,7 +68,7 @@ func NewStandard(fs fsadapter.FS, opts ...StandardOption) *Standard {
}

// Transform transforms the state into a set of files.
func (s *Standard) Transform(ctx context.Context, st *state.State, basePath string) error {
func (s *Standard) Transform(ctx context.Context, basePath string, st *state.State) error {
ctx, task := trace.NewTask(ctx, "transform.Standard.Transform")
defer task.End()
if st == nil {
Expand Down Expand Up @@ -198,7 +200,11 @@ func (s *Standard) saveConversation(conv *types.Conversation) error {
if conv == nil {
return fmt.Errorf("nil conversation")
}
f, err := s.fs.Create(s.nameFn(conv))
name, err := s.nameFn(conv)
if err != nil {
return err
}
f, err := s.fs.Create(name)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/transform/standard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestStandard_Transform(t *testing.T) {
if err != nil {
t.Fatalf("state.Load(): %s", err)
}
if err := s.Transform(ctx, st, whereTheTempIsAt); err != nil {
if err := s.Transform(ctx, whereTheTempIsAt, st); err != nil {
t.Fatal(err)
}
}
13 changes: 13 additions & 0 deletions internal/transform/transform.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package transform

import (
"context"

"github.com/rusq/slackdump/v2/internal/chunk/state"
)

type Interface interface {
// Transform transforms the conversation files from the temporary directory
// with state files and chunk records.
Transform(ctx context.Context, basePath string, st *state.State) error
}

0 comments on commit b2e2da3

Please sign in to comment.