mirror of
				https://github.com/taigrr/wtf
				synced 2025-01-18 04:03:14 -08:00 
			
		
		
		
	Merge pull request #489 from wtfutil/482-missing-position-data-crash
WTF-482 Gracefully handle missing position configuration
This commit is contained in:
		
						commit
						85217be1b5
					
				@ -30,13 +30,6 @@ type Module struct {
 | 
				
			|||||||
	Type string
 | 
						Type string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Position struct {
 | 
					 | 
				
			||||||
	Height int
 | 
					 | 
				
			||||||
	Left   int
 | 
					 | 
				
			||||||
	Top    int
 | 
					 | 
				
			||||||
	Width  int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Sigils struct {
 | 
					type Sigils struct {
 | 
				
			||||||
	Checkbox struct {
 | 
						Checkbox struct {
 | 
				
			||||||
		Checked   string
 | 
							Checked   string
 | 
				
			||||||
@ -64,7 +57,6 @@ type Common struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func NewCommonSettingsFromModule(name, defaultTitle string, moduleConfig *config.Config, globalSettings *config.Config) *Common {
 | 
					func NewCommonSettingsFromModule(name, defaultTitle string, moduleConfig *config.Config, globalSettings *config.Config) *Common {
 | 
				
			||||||
	colorsConfig, _ := globalSettings.Get("wtf.colors")
 | 
						colorsConfig, _ := globalSettings.Get("wtf.colors")
 | 
				
			||||||
	positionPath := "position"
 | 
					 | 
				
			||||||
	sigilsPath := "wtf.sigils"
 | 
						sigilsPath := "wtf.sigils"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	common := Common{
 | 
						common := Common{
 | 
				
			||||||
@ -86,12 +78,7 @@ func NewCommonSettingsFromModule(name, defaultTitle string, moduleConfig *config
 | 
				
			|||||||
			Type: moduleConfig.UString("type", name),
 | 
								Type: moduleConfig.UString("type", name),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Position: Position{
 | 
							Position: NewPositionFromYAML(name, moduleConfig),
 | 
				
			||||||
			Height: moduleConfig.UInt(positionPath + ".height"),
 | 
					 | 
				
			||||||
			Left:   moduleConfig.UInt(positionPath + ".left"),
 | 
					 | 
				
			||||||
			Top:    moduleConfig.UInt(positionPath + ".top"),
 | 
					 | 
				
			||||||
			Width:  moduleConfig.UInt(positionPath + ".width"),
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Enabled:         moduleConfig.UBool("enabled", false),
 | 
							Enabled:         moduleConfig.UBool("enabled", false),
 | 
				
			||||||
		RefreshInterval: moduleConfig.UInt("refreshInterval", 300),
 | 
							RefreshInterval: moduleConfig.UInt("refreshInterval", 300),
 | 
				
			||||||
 | 
				
			|||||||
@ -126,12 +126,15 @@ func LoadConfigFile(filePath string) *config.Config {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	cfg, err := config.ParseYamlFile(absPath)
 | 
						cfg, err := config.ParseYamlFile(absPath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("\n\033[1mERROR:\033[0m Could not load '\033[0;33mconfig.yml\033[0m'.\n")
 | 
							fmt.Println("\n\033[1mERROR:\033[0m Could not load '\033[0;33mconfig.yml\033[0m'.")
 | 
				
			||||||
		fmt.Println("This could mean one of two things:\n")
 | 
							fmt.Println()
 | 
				
			||||||
 | 
							fmt.Println("This could mean one of two things:")
 | 
				
			||||||
 | 
							fmt.Println()
 | 
				
			||||||
		fmt.Println("    1. Your \033[0;33mconfig.yml\033[0m file is missing. Check in \033[0;33m~/.config/wtf\033[0m to see if \033[0;33mconfig.yml\033[0m is there.")
 | 
							fmt.Println("    1. Your \033[0;33mconfig.yml\033[0m file is missing. Check in \033[0;33m~/.config/wtf\033[0m to see if \033[0;33mconfig.yml\033[0m is there.")
 | 
				
			||||||
		fmt.Println("    2. Your \033[0;33mconfig.yml\033[0m file has a syntax error. Try running it through http://www.yamllint.com to check for errors.")
 | 
							fmt.Println("    2. Your \033[0;33mconfig.yml\033[0m file has a syntax error. Try running it through http://www.yamllint.com to check for errors.")
 | 
				
			||||||
		fmt.Println()
 | 
							fmt.Println()
 | 
				
			||||||
		fmt.Printf("Error: \033[0;31m%s\033[0m\n\n", err.Error())
 | 
							fmt.Printf("Error: \033[0;31m%s\033[0m\n\n", err.Error())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										123
									
								
								cfg/position.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								cfg/position.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,123 @@
 | 
				
			|||||||
 | 
					package cfg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/olebedev/config"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						positionPath = "position"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* -------------------- Position Validation -------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type positionValidation struct {
 | 
				
			||||||
 | 
						err  error
 | 
				
			||||||
 | 
						name string
 | 
				
			||||||
 | 
						val  int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (posVal *positionValidation) hasError() bool {
 | 
				
			||||||
 | 
						return posVal.err != nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// String returns the Stringer representation of the positionValidation
 | 
				
			||||||
 | 
					func (posVal *positionValidation) String() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("Invalid value for %s:\t%d", posVal.name, posVal.val)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newPositionValidation(name string, val int, err error) *positionValidation {
 | 
				
			||||||
 | 
						posVal := &positionValidation{
 | 
				
			||||||
 | 
							err:  err,
 | 
				
			||||||
 | 
							name: name,
 | 
				
			||||||
 | 
							val:  val,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return posVal
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* -------------------- Position -------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Position represents the onscreen location of a widget
 | 
				
			||||||
 | 
					type Position struct {
 | 
				
			||||||
 | 
						Height int
 | 
				
			||||||
 | 
						Left   int
 | 
				
			||||||
 | 
						Top    int
 | 
				
			||||||
 | 
						Width  int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewPositionFromYAML creates and returns a new instance of Position
 | 
				
			||||||
 | 
					func NewPositionFromYAML(moduleName string, moduleConfig *config.Config) Position {
 | 
				
			||||||
 | 
						var val int
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						validations := make(map[string]*positionValidation)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Parse the positional data from the config data
 | 
				
			||||||
 | 
						val, err = moduleConfig.Int(positionPath + ".top")
 | 
				
			||||||
 | 
						validations["top"] = newPositionValidation("top", val, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val, err = moduleConfig.Int(positionPath + ".left")
 | 
				
			||||||
 | 
						validations["left"] = newPositionValidation("left", val, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val, err = moduleConfig.Int(positionPath + ".width")
 | 
				
			||||||
 | 
						validations["width"] = newPositionValidation("width", val, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val, err = moduleConfig.Int(positionPath + ".height")
 | 
				
			||||||
 | 
						validations["height"] = newPositionValidation("height", val, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						validatePositions(moduleName, validations)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pos := Position{
 | 
				
			||||||
 | 
							Top:    validations["top"].val,
 | 
				
			||||||
 | 
							Left:   validations["left"].val,
 | 
				
			||||||
 | 
							Width:  validations["width"].val,
 | 
				
			||||||
 | 
							Height: validations["height"].val,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return pos
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* -------------------- Unexported Functions -------------------- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// If any of the position values have an error then we inform the user and exit the app
 | 
				
			||||||
 | 
					// Common examples of invalid position configuration are:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    position:
 | 
				
			||||||
 | 
					//      top: 3
 | 
				
			||||||
 | 
					//      width: 2
 | 
				
			||||||
 | 
					//      height: 1
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    position:
 | 
				
			||||||
 | 
					//      top: 3
 | 
				
			||||||
 | 
					//      # left: 2
 | 
				
			||||||
 | 
					//      width: 2
 | 
				
			||||||
 | 
					//      height: 1
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    position:
 | 
				
			||||||
 | 
					//    top: 3
 | 
				
			||||||
 | 
					//    left: 2
 | 
				
			||||||
 | 
					//    width: 2
 | 
				
			||||||
 | 
					//    height: 1
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					func validatePositions(moduleName string, validations map[string]*positionValidation) {
 | 
				
			||||||
 | 
						var errStr string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, posVal := range validations {
 | 
				
			||||||
 | 
							if posVal.hasError() {
 | 
				
			||||||
 | 
								errStr += fmt.Sprintf("  - %s.\t\033[0;31mError\033[0m %v\n", posVal, posVal.err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if errStr != "" {
 | 
				
			||||||
 | 
							fmt.Println()
 | 
				
			||||||
 | 
							fmt.Printf("\033[0;1mErrors in %s position configuration\033[0m\n", strings.Title(moduleName))
 | 
				
			||||||
 | 
							fmt.Println(errStr)
 | 
				
			||||||
 | 
							fmt.Println("Please check your config.yml file.")
 | 
				
			||||||
 | 
							fmt.Println()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							os.Exit(1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -125,6 +125,8 @@ func (widget *Widget) deleteSelectedTorrent() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	widget.client.TorrentRemove(removePayload)
 | 
						widget.client.TorrentRemove(removePayload)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						widget.display()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// pauseUnpauseTorrent either pauses or unpauses the downloading and seeding of the selected torrent
 | 
					// pauseUnpauseTorrent either pauses or unpauses the downloading and seeding of the selected torrent
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user