refactor to use app struct, integrate printError
This commit is contained in:
parent
6cacf4387a
commit
90015e0261
39
annie.go
39
annie.go
@ -1,39 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/iawia002/lux/downloader"
|
|
||||||
"github.com/iawia002/lux/extractors"
|
|
||||||
)
|
|
||||||
|
|
||||||
func download(videoURL string, wantPlaylist bool, outputPath string) bool {
|
|
||||||
|
|
||||||
data, err := extractors.Extract(videoURL, extractors.Options{
|
|
||||||
Playlist: wantPlaylist,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
// if this error occurs, it means that an error occurred before actually starting to extract data
|
|
||||||
// (there is an error in the preparation step), and the data list is empty.
|
|
||||||
printError(videoURL, err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var isErr bool
|
|
||||||
for _, item := range data {
|
|
||||||
if item.Err != nil {
|
|
||||||
// if this error occurs, the preparation step is normal, but the data extraction is wrong.
|
|
||||||
// the data is an empty struct.
|
|
||||||
printError(item.URL, item.Err)
|
|
||||||
isErr = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
err = downloader.New(downloader.Options{
|
|
||||||
OutputPath: outputPath,
|
|
||||||
}).Download(item)
|
|
||||||
if err != nil {
|
|
||||||
printError(item.URL, err)
|
|
||||||
isErr = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !isErr
|
|
||||||
}
|
|
144
main.go
144
main.go
@ -13,7 +13,10 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/iawia002/lux/downloader"
|
||||||
|
"github.com/iawia002/lux/extractors"
|
||||||
qt "github.com/mappu/miqt/qt6"
|
qt "github.com/mappu/miqt/qt6"
|
||||||
|
"github.com/mappu/miqt/qt6/mainthread"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GUIConfig carries all application configurations.
|
// GUIConfig carries all application configurations.
|
||||||
@ -65,12 +68,6 @@ func LoadGUIConfig() *GUIConfig {
|
|||||||
var settings *qt.QSettings
|
var settings *qt.QSettings
|
||||||
var guiConfig *GUIConfig
|
var guiConfig *GUIConfig
|
||||||
|
|
||||||
func printError(url string, err error) {
|
|
||||||
fmt.Printf(
|
|
||||||
"Downloading %s error:\n%s\n", url, err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
type outputBuffer struct {
|
type outputBuffer struct {
|
||||||
@ -105,9 +102,15 @@ func (b *outputBuffer) attachReader(r io.Reader) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *outputBuffer) addLine(line string) {
|
||||||
|
mainthread.Start(func() {
|
||||||
|
b.addLine_nothread(line)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// addLine adds a line that might end in LF, CRLF, CR, or none of the above (in
|
// addLine adds a line that might end in LF, CRLF, CR, or none of the above (in
|
||||||
// which case an LF is appended). Aware of CR and scroll position.
|
// which case an LF is appended). Aware of CR and scroll position.
|
||||||
func (b *outputBuffer) addLine(line string) {
|
func (b *outputBuffer) addLine_nothread(line string) {
|
||||||
scrollBar := b.textEdit.VerticalScrollBar()
|
scrollBar := b.textEdit.VerticalScrollBar()
|
||||||
currentScroll := scrollBar.Value()
|
currentScroll := scrollBar.Value()
|
||||||
userScrolledBack := currentScroll != scrollBar.Maximum()
|
userScrolledBack := currentScroll != scrollBar.Maximum()
|
||||||
@ -156,18 +159,6 @@ func (b *outputBuffer) readLineAndUpdate() (fullLine string, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
initLanguages()
|
|
||||||
|
|
||||||
qt.QCoreApplication_SetOrganizationName(appAuthor)
|
|
||||||
qt.QCoreApplication_SetOrganizationDomain(appAuthorDomain)
|
|
||||||
|
|
||||||
settings = qt.NewQSettings5()
|
|
||||||
guiConfig = LoadGUIConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
func initAboutWindow(parent *qt.QWidget) *qt.QDialog {
|
func initAboutWindow(parent *qt.QWidget) *qt.QDialog {
|
||||||
w := qt.NewQDialog(parent)
|
w := qt.NewQDialog(parent)
|
||||||
label := qt.NewQLabel3(about)
|
label := qt.NewQLabel3(about)
|
||||||
@ -178,12 +169,22 @@ func initAboutWindow(parent *qt.QWidget) *qt.QDialog {
|
|||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
type AnnieGuiApp struct {
|
||||||
qt.NewQApplication(os.Args)
|
*qt.QMainWindow
|
||||||
|
|
||||||
|
urlLineEdit *qt.QLineEdit
|
||||||
|
output *outputBuffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAnnieGuiApp() *AnnieGuiApp {
|
||||||
|
|
||||||
window := qt.NewQMainWindow2()
|
window := qt.NewQMainWindow2()
|
||||||
window.SetWindowTitle(appName)
|
window.SetWindowTitle(appName)
|
||||||
|
|
||||||
|
app := AnnieGuiApp{
|
||||||
|
QMainWindow: window,
|
||||||
|
}
|
||||||
|
|
||||||
const WindowStateVersion = 0
|
const WindowStateVersion = 0
|
||||||
|
|
||||||
window.OnCloseEvent(func(super func(event *qt.QCloseEvent), event *qt.QCloseEvent) {
|
window.OnCloseEvent(func(super func(event *qt.QCloseEvent), event *qt.QCloseEvent) {
|
||||||
@ -218,7 +219,7 @@ func main() {
|
|||||||
aboutWindow.Raise()
|
aboutWindow.Raise()
|
||||||
})
|
})
|
||||||
|
|
||||||
urlLineEdit := qt.NewQLineEdit(nil)
|
app.urlLineEdit = qt.NewQLineEdit(nil)
|
||||||
|
|
||||||
folderLineEdit := qt.NewQLineEdit3(guiConfig.DestinationFolder)
|
folderLineEdit := qt.NewQLineEdit3(guiConfig.DestinationFolder)
|
||||||
folderLineEdit.SetReadOnly(true)
|
folderLineEdit.SetReadOnly(true)
|
||||||
@ -246,7 +247,7 @@ func main() {
|
|||||||
|
|
||||||
inputFormLayout := qt.NewQFormLayout(nil)
|
inputFormLayout := qt.NewQFormLayout(nil)
|
||||||
inputFormLayout.SetFieldGrowthPolicy(qt.QFormLayout__AllNonFixedFieldsGrow)
|
inputFormLayout.SetFieldGrowthPolicy(qt.QFormLayout__AllNonFixedFieldsGrow)
|
||||||
inputFormLayout.AddRow3(tr("Video URL"), urlLineEdit.QWidget)
|
inputFormLayout.AddRow3(tr("Video URL"), app.urlLineEdit.QWidget)
|
||||||
inputFormLayout.AddRow4(tr("Destination folder"), folderHBoxLayout.QLayout)
|
inputFormLayout.AddRow4(tr("Destination folder"), folderHBoxLayout.QLayout)
|
||||||
inputFormLayout.AddRow3(tr("Download playlists"), playlistCheckBox.QWidget)
|
inputFormLayout.AddRow3(tr("Download playlists"), playlistCheckBox.QWidget)
|
||||||
|
|
||||||
@ -258,23 +259,40 @@ func main() {
|
|||||||
monospaceFont := qt.NewQFont2("Courier")
|
monospaceFont := qt.NewQFont2("Courier")
|
||||||
monospaceFont.SetStyleHint(qt.QFont__Monospace)
|
monospaceFont.SetStyleHint(qt.QFont__Monospace)
|
||||||
outputTextEdit.SetFont(monospaceFont)
|
outputTextEdit.SetFont(monospaceFont)
|
||||||
output := newOutputBuffer(outputTextEdit)
|
|
||||||
output.addLine(tr("Awaiting user input"))
|
app.output = newOutputBuffer(outputTextEdit)
|
||||||
|
app.output.addLine(tr("Awaiting user input"))
|
||||||
|
|
||||||
downloadButton := qt.NewQPushButton3(tr("Download"))
|
downloadButton := qt.NewQPushButton3(tr("Download"))
|
||||||
downloadButton.OnClicked(func() {
|
downloadButton.OnClicked(app.StartDownload)
|
||||||
url := strings.TrimSpace(urlLineEdit.Text())
|
|
||||||
if len(url) > 0 {
|
layout := qt.NewQVBoxLayout2()
|
||||||
output.addLine(time.Now().Format("15:04:05 ") + tr("Download started"))
|
layout.AddLayout2(inputFormLayout.QLayout, 0)
|
||||||
|
layout.AddWidget3(downloadButton.QWidget, 0, 0)
|
||||||
|
layout.AddWidget3(outputTextEdit.QWidget, 1, 0)
|
||||||
|
centralWidget.SetLayout(layout.QLayout)
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
return &app
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *AnnieGuiApp) StartDownload() {
|
||||||
|
url := strings.TrimSpace(app.urlLineEdit.Text())
|
||||||
|
if len(url) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app.output.addLine(time.Now().Format("15:04:05 ") + tr("Download started"))
|
||||||
|
|
||||||
savedStdout := os.Stdout
|
savedStdout := os.Stdout
|
||||||
r, w, _ := os.Pipe()
|
r, w, _ := os.Pipe()
|
||||||
output.attachReader(r)
|
app.output.attachReader(r)
|
||||||
os.Stdout = w
|
os.Stdout = w
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
_, err := output.readLineAndUpdate()
|
_, err := app.output.readLineAndUpdate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
break
|
break
|
||||||
@ -283,26 +301,70 @@ func main() {
|
|||||||
}
|
}
|
||||||
// fmt.Fprint(savedStdout, line)
|
// fmt.Fprint(savedStdout, line)
|
||||||
}
|
}
|
||||||
output.addLine("")
|
app.output.addLine("")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
printError := func(url string, err error) {
|
||||||
|
app.output.addLine(fmt.Sprintf(
|
||||||
|
"Downloading %s error:\n%s\n", url, err,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if !download(url, guiConfig.PlaylistEnabled, guiConfig.DestinationFolder) {
|
|
||||||
fmt.Println(tr("On network errors, e.g. HTTP 403, please retry a few times."))
|
data, err := extractors.Extract(url, extractors.Options{
|
||||||
|
Playlist: guiConfig.PlaylistEnabled,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
// if this error occurs, it means that an error occurred before actually starting to extract data
|
||||||
|
// (there is an error in the preparation step), and the data list is empty.
|
||||||
|
printError(url, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var isErr bool
|
||||||
|
for _, item := range data {
|
||||||
|
if item.Err != nil {
|
||||||
|
// if this error occurs, the preparation step is normal, but the data extraction is wrong.
|
||||||
|
// the data is an empty struct.
|
||||||
|
printError(item.URL, item.Err)
|
||||||
|
isErr = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = downloader.New(downloader.Options{
|
||||||
|
OutputPath: guiConfig.DestinationFolder,
|
||||||
|
}).Download(item)
|
||||||
|
if err != nil {
|
||||||
|
printError(item.URL, err)
|
||||||
|
isErr = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isErr {
|
||||||
|
app.output.addLine(tr("On network errors, e.g. HTTP 403, please retry a few times."))
|
||||||
}
|
}
|
||||||
w.Close()
|
w.Close()
|
||||||
os.Stdout = savedStdout
|
os.Stdout = savedStdout
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
layout := qt.NewQVBoxLayout2()
|
func main() {
|
||||||
layout.AddLayout2(inputFormLayout.QLayout, 0)
|
flag.Parse()
|
||||||
layout.AddWidget3(downloadButton.QWidget, 0, 0)
|
|
||||||
layout.AddWidget3(outputTextEdit.QWidget, 1, 0)
|
|
||||||
centralWidget.SetLayout(layout.QLayout)
|
|
||||||
|
|
||||||
window.Show()
|
initLanguages()
|
||||||
|
|
||||||
|
qt.QCoreApplication_SetOrganizationName(appAuthor)
|
||||||
|
qt.QCoreApplication_SetOrganizationDomain(appAuthorDomain)
|
||||||
|
|
||||||
|
settings = qt.NewQSettings5()
|
||||||
|
guiConfig = LoadGUIConfig()
|
||||||
|
|
||||||
|
qt.NewQApplication(os.Args)
|
||||||
|
|
||||||
|
app := NewAnnieGuiApp()
|
||||||
|
|
||||||
|
app.Show()
|
||||||
|
|
||||||
sigs := make(chan os.Signal)
|
sigs := make(chan os.Signal)
|
||||||
signal.Notify(sigs, syscall.SIGSEGV, syscall.SIGABRT)
|
signal.Notify(sigs, syscall.SIGSEGV, syscall.SIGABRT)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user