Skip to content

Commit

Permalink
Bootstrap controller implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
vpoluyaktov committed Nov 11, 2023
1 parent 11bd7cf commit bb7c392
Show file tree
Hide file tree
Showing 25 changed files with 310 additions and 104 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,5 @@ Since the copyrights for the majority of old-time radio shows have expired and m


## TODO:
- Implement Search/Replace for Description on Chapters page
- Finish Default Settings screen
- Create an audiobook Settings screen


1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require (
)

require (
github.com/hashicorp/go-version v1.6.0
github.com/rivo/tview v0.0.0-20230406072732-e22ce9588bb4
github.com/stretchr/testify v1.8.3
golang.org/x/net v0.17.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ github.com/gdamore/tcell/v2 v2.6.0 h1:OKbluoP9VYmJwZwq/iLb4BxwKcwGthaa1YNBJIyCyS
github.com/gdamore/tcell/v2 v2.6.0/go.mod h1:be9omFATkdr0D9qewWW3d+MEvl5dha+Etb5y65J2H8Y=
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
Expand Down
18 changes: 9 additions & 9 deletions internal/controller/audiobookShelfController.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package controller

import (
"github.com/vpoluyaktov/abb_ia/internal/audiobookshelf"
"github.com/vpoluyaktov/abb_ia/internal/config"
"github.com/vpoluyaktov/abb_ia/internal/dto"
"github.com/vpoluyaktov/abb_ia/internal/logger"
"github.com/vpoluyaktov/abb_ia/internal/mq"
Expand All @@ -13,10 +12,10 @@ type AudiobookshelfController struct {
}

func NewAudiobookshelfController(dispatcher *mq.Dispatcher) *AudiobookshelfController {
dc := &AudiobookshelfController{}
dc.mq = dispatcher
dc.mq.RegisterListener(mq.AudiobookshelfController, dc.dispatchMessage)
return dc
c := &AudiobookshelfController{}
c.mq = dispatcher
c.mq.RegisterListener(mq.AudiobookshelfController, c.dispatchMessage)
return c
}

func (c *AudiobookshelfController) checkMQ() {
Expand All @@ -37,10 +36,11 @@ func (c *AudiobookshelfController) dispatchMessage(m *mq.Message) {

func (c *AudiobookshelfController) audiobookshelfScan(cmd *dto.AudiobookshelfScanCommand) {
logger.Info(mq.AudiobookshelfController + " received " + cmd.String())
url := config.Instance().GetAudiobookshelfUrl()
username := config.Instance().GetAudiobookshelfUser()
password := config.Instance().GetAudiobookshelfPassword()
libraryName := config.Instance().GetAudiobookshelfLibrary()
ab := cmd.Audiobook
url := ab.Config.GetAudiobookshelfUrl()
username := ab.Config.GetAudiobookshelfUser()
password := ab.Config.GetAudiobookshelfPassword()
libraryName := ab.Config.GetAudiobookshelfLibrary()

if url != "" && username != "" && password != "" && libraryName != "" {
loginResp, err := audiobookshelf.Login(url+"/login", username, password)
Expand Down
75 changes: 75 additions & 0 deletions internal/controller/bootController.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package controller

import (
"time"

"github.com/vpoluyaktov/abb_ia/internal/config"
"github.com/vpoluyaktov/abb_ia/internal/dto"
"github.com/vpoluyaktov/abb_ia/internal/logger"
"github.com/vpoluyaktov/abb_ia/internal/mq"
"github.com/vpoluyaktov/abb_ia/internal/utils"
)

type BootController struct {
mq *mq.Dispatcher
}

func NewBootController(dispatcher *mq.Dispatcher) *BootController {
c := &BootController{}
c.mq = dispatcher
c.mq.RegisterListener(mq.BootController, c.dispatchMessage)
go c.bootStrap(&dto.BootstrapCommand{})
return c
}

func (c *BootController) checkMQ() {
m := c.mq.GetMessage(mq.BootController)
if m != nil {
c.dispatchMessage(m)
}
}

func (c *BootController) dispatchMessage(m *mq.Message) {
switch dto := m.Dto.(type) {
case *dto.BootstrapCommand:
go c.bootStrap(dto)
default:
m.UnsupportedTypeError(mq.BootController)
}
}

func (c *BootController) bootStrap(cmd *dto.BootstrapCommand) {
// wait for all components to initialize
time.Sleep(3 * time.Second)
if c.checkFFmpeg() {
c.checkNewVersion()
}
}

func (c *BootController) checkFFmpeg() bool {
if !(utils.CommandExists("ffmpeg") && utils.CommandExists("ffprobe")) {
logger.Fatal("Bootstrap: ffmpeg or ffprobe command not found")
c.mq.SendMessage(mq.BootController, mq.SearchPage, &dto.FFMPEGNotFoundError{}, true)
return false
}
return true
}

func (c *BootController) checkNewVersion() {

latestVersion, err := utils.GetLatestVersion("vpoluyaktov", "abb_ia")
if err != nil {
logger.Error("Can't check new version: " + err.Error())
return
}

result, err := utils.CompareVersions(latestVersion, config.Instance().AppVersion())
if err != nil {
logger.Error("Can not compare versions: " + err.Error())
return
}

if result > 0 {
c.mq.SendMessage(mq.BootController, mq.SearchPage, &dto.NewAppVersionFound{CurrentVersion: config.Instance().AppVersion(), NewVersion: latestVersion}, true)
}
}
15 changes: 7 additions & 8 deletions internal/controller/buildController.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"strings"
"time"

"github.com/vpoluyaktov/abb_ia/internal/config"
"github.com/vpoluyaktov/abb_ia/internal/dto"
"github.com/vpoluyaktov/abb_ia/internal/ffmpeg"
"github.com/vpoluyaktov/abb_ia/internal/utils"
Expand All @@ -37,10 +36,10 @@ type fileBuild struct {
}

func NewBuildController(dispatcher *mq.Dispatcher) *BuildController {
dc := &BuildController{}
dc.mq = dispatcher
dc.mq.RegisterListener(mq.BuildController, dc.dispatchMessage)
return dc
c := &BuildController{}
c.mq = dispatcher
c.mq.RegisterListener(mq.BuildController, c.dispatchMessage)
return c
}

func (c *BuildController) checkMQ() {
Expand Down Expand Up @@ -75,7 +74,7 @@ func (c *BuildController) startBuild(cmd *dto.BuildCommand) {
// calculate output file names
for i := range c.ab.Parts {
part := &c.ab.Parts[i]
filePath := filepath.Join(config.Instance().GetOutputDir(), c.ab.Author+" - "+c.ab.Title)
filePath := filepath.Join(c.ab.Config.GetOutputDir(), c.ab.Author+" - "+c.ab.Title)
if len(c.ab.Parts) > 1 {
filePath = filePath + fmt.Sprintf(", Part %02d", i+1)
}
Expand All @@ -96,7 +95,7 @@ func (c *BuildController) startBuild(cmd *dto.BuildCommand) {
// build audiobook parts
c.stopFlag = false
c.filesBuild = make([]fileBuild, len(c.ab.Parts))
jd := utils.NewJobDispatcher(config.Instance().GetConcurrentEncoders())
jd := utils.NewJobDispatcher(c.ab.Config.GetConcurrentEncoders())
for i := range c.ab.Parts {
jd.AddJob(i, c.buildAudiobookPart, c.ab, i)
}
Expand Down Expand Up @@ -162,7 +161,7 @@ func (c *BuildController) createMetadata(ab *dto.Audiobook) {
}

func (c *BuildController) downloadCoverImage(ab *dto.Audiobook) error {
filePath := filepath.Join(config.Instance().GetOutputDir(), ab.Author+" - "+ab.Title)
filePath := filepath.Join(ab.Config.GetOutputDir(), ab.Author+" - "+ab.Title)
if strings.HasSuffix(ab.CoverURL, ".jpg") {
ab.CoverFile = filePath + ".jpg"
} else if strings.HasSuffix(ab.CoverURL, ".png") {
Expand Down
15 changes: 7 additions & 8 deletions internal/controller/chaptersController.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"regexp"
"strings"

"github.com/vpoluyaktov/abb_ia/internal/config"
"github.com/vpoluyaktov/abb_ia/internal/dto"
"github.com/vpoluyaktov/abb_ia/internal/ffmpeg"
"github.com/vpoluyaktov/abb_ia/internal/logger"
Expand All @@ -26,10 +25,10 @@ type ChaptersController struct {
* This code is useful for creating a new ChaptersController instance and registering it with the message queue dispatcher. This allows the ChaptersController to receive messages from the message queue and dispatch them to the appropriate handler.
**/
func NewChaptersController(dispatcher *mq.Dispatcher) *ChaptersController {
dc := &ChaptersController{}
dc.mq = dispatcher
dc.mq.RegisterListener(mq.ChaptersController, dc.dispatchMessage)
return dc
c := &ChaptersController{}
c.mq = dispatcher
c.mq.RegisterListener(mq.ChaptersController, c.dispatchMessage)
return c
}

func (c *ChaptersController) checkMQ() {
Expand Down Expand Up @@ -76,7 +75,7 @@ func (c *ChaptersController) createChapters(cmd *dto.ChaptersCreate) {

c.ab = cmd.Audiobook

if config.Instance().IsShortenTitle() {
if c.ab.Config.IsShortenTitle() {
c.ab.Title = strings.ReplaceAll(c.ab.Title, " - Single Episodes", "")
c.ab.Author = strings.ReplaceAll(c.ab.Author, "Old Time Radio Researchers Group", "OTRR")
}
Expand Down Expand Up @@ -109,7 +108,7 @@ func (c *ChaptersController) createChapters(cmd *dto.ChaptersCreate) {
offset += mp3.Duration()
chapterNo++
chapterFiles = []dto.Mp3File{}
if partSize >= int64(config.Instance().GetMaxFileSizeMb())*1024*1024 || i == len(c.ab.Mp3Files)-1 {
if partSize >= int64(c.ab.Config.GetMaxFileSizeMb())*1024*1024 || i == len(c.ab.Mp3Files)-1 {
part := dto.Part{Number: partNo, Size: partSize, Duration: partDuration, Chapters: partChapters}
c.ab.Parts = append(c.ab.Parts, part)
partNo++
Expand All @@ -134,7 +133,7 @@ func (c *ChaptersController) searchReplaceDescription(cmd *dto.SearchReplaceDesc
if err != nil {
return
}

description := re.ReplaceAllString(ab.Description, replaceStr)
ab.Description = description
c.mq.SendMessage(mq.ChaptersController, mq.ChaptersPage, &dto.RefreshDescriptionCommand{Audiobook: cmd.Audiobook}, true)
Expand Down
13 changes: 6 additions & 7 deletions internal/controller/cleanupController.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package controller
import (
"os"

"github.com/vpoluyaktov/abb_ia/internal/config"
"github.com/vpoluyaktov/abb_ia/internal/dto"
"github.com/vpoluyaktov/abb_ia/internal/logger"
"github.com/vpoluyaktov/abb_ia/internal/mq"
Expand All @@ -15,10 +14,10 @@ type CleanupController struct {
}

func NewCleanupController(dispatcher *mq.Dispatcher) *CleanupController {
dc := &CleanupController{}
dc.mq = dispatcher
dc.mq.RegisterListener(mq.CleanupController, dc.dispatchMessage)
return dc
c := &CleanupController{}
c.mq = dispatcher
c.mq.RegisterListener(mq.CleanupController, c.dispatchMessage)
return c
}

func (c *CleanupController) checkMQ() {
Expand All @@ -41,14 +40,14 @@ func (c *CleanupController) cleanUp(cmd *dto.CleanupCommand) {
logger.Info(mq.CleanupController + " received " + cmd.String())
c.ab = cmd.Audiobook

if !(config.Instance().IsSaveMock() || config.Instance().IsUseMock()) {
if !(c.ab.Config.IsSaveMock() || c.ab.Config.IsUseMock()) {
os.RemoveAll(c.ab.OutputDir)
}
for _, part := range c.ab.Parts {
os.Remove(part.AACFile)
os.Remove(part.FListFile)
os.Remove(part.MetadataFile)
if config.Instance().IsCopyToAudiobookshelf() {
if c.ab.Config.IsCopyToAudiobookshelf() {
os.Remove(part.M4BFile)
}
}
Expand Down
1 change: 1 addition & 0 deletions internal/controller/conductor.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func NewConductor(dispatcher *mq.Dispatcher) *Conductor {
c.controllers = append(c.controllers, NewCopyController(c.dispatcher))
c.controllers = append(c.controllers, NewAudiobookshelfController(c.dispatcher))
c.controllers = append(c.controllers, NewCleanupController(c.dispatcher))
c.controllers = append(c.controllers, NewBootController(c.dispatcher))
return c
}

Expand Down
8 changes: 4 additions & 4 deletions internal/controller/configController.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ type ConfigController struct {
}

func NewConfigController(dispatcher *mq.Dispatcher) *ConfigController {
sc := &ConfigController{}
sc.mq = dispatcher
sc.mq.RegisterListener(mq.ConfigController, sc.dispatchMessage)
return sc
c := &ConfigController{}
c.mq = dispatcher
c.mq.RegisterListener(mq.ConfigController, c.dispatchMessage)
return c
}

func (c *ConfigController) checkMQ() {
Expand Down
13 changes: 6 additions & 7 deletions internal/controller/copyController.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"path/filepath"
"time"

"github.com/vpoluyaktov/abb_ia/internal/config"
"github.com/vpoluyaktov/abb_ia/internal/dto"
"github.com/vpoluyaktov/abb_ia/internal/utils"

Expand Down Expand Up @@ -60,10 +59,10 @@ func (pr *ProgressReader) Read(p []byte) (int, error) {
}

func NewCopyController(dispatcher *mq.Dispatcher) *CopyController {
dc := &CopyController{}
dc.mq = dispatcher
dc.mq.RegisterListener(mq.CopyController, dc.dispatchMessage)
return dc
c := &CopyController{}
c.mq = dispatcher
c.mq.RegisterListener(mq.CopyController, c.dispatchMessage)
return c
}

func (c *CopyController) checkMQ() {
Expand Down Expand Up @@ -109,7 +108,7 @@ func (c *CopyController) startCopy(cmd *dto.CopyCommand) {

c.stopFlag = false
c.filesCopy = make([]fileCopy, len(c.ab.Parts))
jd := utils.NewJobDispatcher(config.Instance().GetConcurrentDownloaders())
jd := utils.NewJobDispatcher(c.ab.Config.GetConcurrentDownloaders())
for i := range c.ab.Parts {
jd.AddJob(i, c.copyAudiobookPart, c.ab, i)
}
Expand Down Expand Up @@ -140,7 +139,7 @@ func (c *CopyController) copyAudiobookPart(ab *dto.Audiobook, partId int) {
defer file.Close()

// Calculate Audiobookshelf directory structure (see: https://www.audiobookshelf.org/docs#book-directory-structure)
destPath := filepath.Join(config.Instance().GetAudiobookshelfDir(), ab.Author)
destPath := filepath.Join(ab.Config.GetAudiobookshelfDir(), ab.Author)
if ab.Series != "" {
destPath = filepath.Join(destPath, ab.Author+" - "+ab.Series)
}
Expand Down
15 changes: 7 additions & 8 deletions internal/controller/downloadController.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"path/filepath"
"time"

"github.com/vpoluyaktov/abb_ia/internal/config"
"github.com/vpoluyaktov/abb_ia/internal/dto"
"github.com/vpoluyaktov/abb_ia/internal/ia_client"
"github.com/vpoluyaktov/abb_ia/internal/logger"
Expand All @@ -29,10 +28,10 @@ type fileDownload struct {
}

func NewDownloadController(dispatcher *mq.Dispatcher) *DownloadController {
dc := &DownloadController{}
dc.mq = dispatcher
dc.mq.RegisterListener(mq.DownloadController, dc.dispatchMessage)
return dc
c := &DownloadController{}
c.mq = dispatcher
c.mq.RegisterListener(mq.DownloadController, c.dispatchMessage)
return c
}

func (c *DownloadController) checkMQ() {
Expand Down Expand Up @@ -70,18 +69,18 @@ func (c *DownloadController) startDownload(cmd *dto.DownloadCommand) {
c.ab.Title = item.Title
c.ab.Description = item.Description
c.ab.CoverURL = item.CoverUrl
c.ab.OutputDir = utils.SanitizeFilePath(filepath.Join(config.Instance().GetOutputDir(), item.ID))
c.ab.OutputDir = utils.SanitizeFilePath(filepath.Join(c.ab.Config.GetOutputDir(), item.ID))
c.ab.TotalSize = item.TotalSize
c.ab.TotalDuration = item.TotalLength

// update Book info on UI
c.mq.SendMessage(mq.DownloadController, mq.DownloadPage, &dto.DisplayBookInfoCommand{Audiobook: c.ab}, true)

// download files
ia := ia_client.New(config.Instance().GetSearchRowsMax(), config.Instance().IsUseMock(), config.Instance().IsSaveMock())
ia := ia_client.New(c.ab.Config.GetSearchRowsMax(), c.ab.Config.IsUseMock(), c.ab.Config.IsSaveMock())
c.stopFlag = false
c.files = make([]fileDownload, len(item.AudioFiles))
jd := utils.NewJobDispatcher(config.Instance().GetConcurrentDownloaders())
jd := utils.NewJobDispatcher(c.ab.Config.GetConcurrentDownloaders())
for i, iaFile := range item.AudioFiles {
localFileName := utils.SanitizeFilePath(filepath.Join(item.Dir, iaFile.Name))
c.ab.Mp3Files = append(c.ab.Mp3Files, dto.Mp3File{Number: i, FileName: localFileName, Size: iaFile.Size, Duration: iaFile.Length})
Expand Down
Loading

0 comments on commit bb7c392

Please sign in to comment.