Signed-off-by: blob42 <contact@blob42.xyz>
This commit is contained in:
blob42 2024-10-10 18:04:01 +02:00
parent 427831cf02
commit b14a9f397d
6 changed files with 60 additions and 58 deletions

View File

@ -25,8 +25,8 @@ import (
"strings"
"github.com/blob42/gosuki/cmd"
"github.com/blob42/gosuki/pkg/config"
"github.com/blob42/gosuki/internal/utils"
"github.com/blob42/gosuki/pkg/config"
"github.com/gobuffalo/flect"
"github.com/urfave/cli/v2"
@ -37,25 +37,25 @@ const (
)
var globalFirefoxFlags = []cli.Flag{
// This allows us to register dynamic cli flags which get converted to
// config.Configurator options.
// The flag must be given a name in the form `--firefox-<flag>`.
// This allows us to register dynamic cli flags which get converted to
// config.Configurator options.
// The flag must be given a name in the form `--firefox-<flag>` or `--ff-<flag>`.
&cli.StringFlag{
Name: FirefoxProfileFlag,
Name: FirefoxProfileFlag,
Category: "firefox",
Usage: "set the default firefox `PROFILE` to use",
Usage: "set the default firefox `PROFILE` to use",
},
&cli.BoolFlag{
Name: "ff-watch-all-profiles",
Category: "firefox",
Usage: "watch all firefox profiles for changes",
Aliases: []string{"ff-watch-all"},
Name: "ff-watch-all-profiles",
Category: "firefox",
Usage: "watch all firefox profiles for changes",
Aliases: []string{"ff-watch-all"},
},
}
// Firefox global flags must start with --firefox-<flag name here>
// NOTE: is called in *cli.App.Before callback
//TODO: refactor module flags/options mangement to generate flags from config options
// TODO: refactor module flags/options mangement to generate flags from config options
func globalCommandFlagsManager(c *cli.Context) error {
log.Debugf("<%s> registering global flag manager", BrowserName)
for _, f := range c.App.Flags {
@ -84,7 +84,7 @@ func globalCommandFlagsManager(c *cli.Context) error {
}
//TODO: document this feature
// extracts global options that start with --firefox-*
// extracts global options that start with --firefox-*
optionName := flect.Pascalize(strings.Join(sp[1:], " "))
var destVal interface{}
@ -119,7 +119,7 @@ func init() {
// register dynamic flag manager for firefox
cmd.RegBeforeHook(BrowserName, globalCommandFlagsManager)
for _, flag := range globalFirefoxFlags {
cmd.RegGlobalModFlag(BrowserName, flag)
}
for _, flag := range globalFirefoxFlags {
cmd.RegGlobalModFlag(BrowserName, flag)
}
}

View File

@ -23,9 +23,9 @@
package firefox
import (
"github.com/blob42/gosuki/pkg/config"
"github.com/blob42/gosuki/internal/database"
"github.com/blob42/gosuki/pkg/browsers/mozilla"
"github.com/blob42/gosuki/pkg/config"
"github.com/blob42/gosuki/pkg/modules"
"github.com/blob42/gosuki/pkg/parsing"
"github.com/blob42/gosuki/pkg/profiles"
@ -35,16 +35,15 @@ import (
const (
//TODO: auto detect firefox base dir based on OS and installed flavors
// FirefoxBaseDir = "$HOME/.mozilla/firefox"
DefaultProfile = "default"
DefaultProfile = "default"
// Default flavour to use
BrowserName = mozilla.FirefoxFlavour
)
var (
// firefox global config state.
// firefox global config state.
FFConfig *FirefoxConfig
ffProfileLoader = &profiles.INIProfileLoader{
@ -60,7 +59,7 @@ var (
// FirefoxConfig implements the Configurator interface
// which allows it to register and set field through the Configurator.
//
// It is also used alongside cli_flags.go to dynamically register cli flags
// It is also used alongside cmd_flags.go to dynamically register cli flags
// that can change this config (struct fields) from command line at runtime.
//
// The struct schema defines the parameters to pass on to firefox that can be
@ -69,16 +68,16 @@ var (
// config file options will only be accepted if they are defined here.
type FirefoxConfig struct {
// Default data source name query options for `places.sqlite` db
PlacesDSN database.DsnOptions `toml:"-"`
PlacesDSN database.DsnOptions `toml:"-"`
modules.ProfilePrefs `toml:"profile_options" mapstructure:"profile_options"`
//TEST: ignore this field in config.Configurator interface
//TEST: ignore this field in config.Configurator interface
// Embed base browser config
*modules.BrowserConfig `toml:"-"`
*modules.BrowserConfig `toml:"-"`
}
//REFACT: move logic to modules package and use interface as input
// REFACT: move logic to modules package and use interface as input
func setBookmarkDir(fc *FirefoxConfig) {
var err error
@ -102,11 +101,11 @@ func NewFirefoxConfig() *FirefoxConfig {
cfg := &FirefoxConfig{
BrowserConfig: &modules.BrowserConfig{
Name: BrowserName,
Type: modules.TFirefox,
BkFile: mozilla.PlacesFile,
Name: BrowserName,
Type: modules.TFirefox,
BkFile: mozilla.PlacesFile,
NodeTree: &tree.Node{
Name: mozilla.RootName,
Name: mozilla.RootName,
Parent: nil,
Type: tree.RootNode,
},
@ -114,8 +113,7 @@ func NewFirefoxConfig() *FirefoxConfig {
UseFileWatcher: true,
// NOTE: see parsing.Hook to add custom parsing logic for each
// parsed bookmark node
UseHooks: []string{"notify-send"},
UseHooks: []string{"notify-send"},
},
// Default data source name query options for `places.sqlite` db
@ -146,7 +144,6 @@ func NewFirefoxConfig() *FirefoxConfig {
return cfg
}
func init() {
FFConfig = NewFirefoxConfig()
config.RegisterConfigurator(BrowserName, config.AsConfigurator(FFConfig))

View File

@ -30,11 +30,12 @@ import (
)
const (
// Note that user.js will be read every time Firefox starts, so changes made to it will take effect immediately.
// Also when Firefox is updated, it may update also the prefs.js file, and your
// modification could be lost. Therefore it is better to use user.js to set such
// preferences which are not possible to set from the Firefox settings.
//TODO!: create file if it does not exist
// Note that user.js will be read every time Firefox starts, so changes made to it will take effect immediately.
// Also when Firefox is updated, it may update also the prefs.js file, and your
// modification could be lost. Therefore it is better to use user.js to set such
// preferences which are not possible to set from the Firefox settings.
//TODO!: create file if it does not exist
PrefsFile = "user.js"
// Parses vales in prefs.js under the form:

View File

@ -19,7 +19,6 @@
// You should have received a copy of the GNU Affero General Public License along with
// gosuki. If not, see <http://www.gnu.org/licenses/>.
// TODO: generalize this package to handle any mozilla based browser
package mozilla
import (
@ -40,8 +39,8 @@ const (
// Browser flavour names
const (
FirefoxFlavour = "firefox"
LibreWolfFlavour = "librewolf"
FirefoxFlavour = "firefox"
LibreWolfFlavour = "librewolf"
)
var (
@ -54,13 +53,13 @@ var (
//TODO: multi platform
// linux mozilla browsers
MozBrowsers = map[string]profiles.BrowserFlavour{
FirefoxFlavour: { FirefoxFlavour , "~/.mozilla/firefox"} ,
LibreWolfFlavour: { LibreWolfFlavour , "~/.librewolf"} ,
FirefoxFlavour: {FirefoxFlavour, "~/.mozilla/firefox"},
LibreWolfFlavour: {LibreWolfFlavour, "~/.librewolf"},
}
)
type MozProfileManager struct {
PathResolver profiles.PathResolver
PathResolver profiles.PathResolver
}
func NewMozProfileManager(resolver profiles.PathResolver) *MozProfileManager {
@ -74,9 +73,9 @@ func (pm *MozProfileManager) loadINIProfile(r profiles.PathResolver) (*ini.File,
log.Debugf("loading profile from <%s>", r.GetPath())
profilePath, err := utils.ExpandPath(r.GetPath())
if err != nil {
return nil, err
return nil, err
}
pFile, err := ini.Load(profilePath)
if err != nil {
return nil, err
@ -85,7 +84,7 @@ func (pm *MozProfileManager) loadINIProfile(r profiles.PathResolver) (*ini.File,
return pFile, nil
}
//TODO: should also handle flavours
// TODO: handle browser flavours (ie. firefox forks )
func (pm *MozProfileManager) GetProfiles(flavour string) ([]*profiles.Profile, error) {
var pFile *ini.File
var err error
@ -105,7 +104,7 @@ func (pm *MozProfileManager) GetProfiles(flavour string) ([]*profiles.Profile, e
for _, section := range sections {
if ReIniProfiles.MatchString(section.Name()) {
p := &profiles.Profile{
Id: section.Name(),
Id: section.Name(),
BaseDir: f.BaseDir,
}

View File

@ -54,7 +54,7 @@ type Configurator interface {
MapFrom(interface{}) error
}
// Used to store the global config
// Global config holder
type Config map[string]interface{}
func (c Config) Set(opt string, v interface{}) error {
@ -70,6 +70,8 @@ func (c Config) Dump() map[string]interface{} {
return c
}
// TODO: document usage, help for implmenters
// TEST: is this a sane way to use Decode ?
func (c Config) MapFrom(src interface{}) error {
// Not used here
return nil
@ -111,8 +113,10 @@ func (ac AutoConfigurator) MapFrom(src interface{}) error {
return mapstructure.Decode(src, ac.c)
}
// AsConfigurator generates implements a default Configurator for a given struct
// or custom type. Use this to handle module options.
func AsConfigurator(c interface{}) Configurator {
return AutoConfigurator{c}
return AutoConfigurator{c}
}
// Register a global option ie. under [global] in toml file
@ -133,8 +137,8 @@ func GetModOpt(module string, opt string) (interface{}, error) {
// If the module is not a configurator, a simple map[string]interface{} will be
// created for it.
//TODO: check if generics can be used here to avoid interface{} type
//TODO: add support for option description that can be used in cli help
// TODO: check if generics can be used here to avoid interface{} type
// TODO: add support for option description that can be used in cli help
func RegisterModuleOpt(module string, opt string, val interface{}) error {
log.Debugf("Setting option for module <%s>: %s = %v", module, opt, val)
if _, ok := configs[module]; !ok {
@ -145,8 +149,10 @@ func RegisterModuleOpt(module string, opt string, val interface{}) error {
if err := dest.Set(opt, val); err != nil {
return err
}
watchAll, _ := configs[module].Get("WatchAllProfiles")
log.Debugf("[%s]WATCH_ALL: %v", module, watchAll)
//DEBUG:
// watchAll, _ := configs[module].Get("WatchAllProfiles")
// log.Debugf("[%s]WATCH_ALL: %v", module, watchAll)
return nil
}
@ -172,7 +178,6 @@ func GetModule(module string) Configurator {
return nil
}
// Hooks registered here will be executed after the config package has finished
// loading the conf
func RegisterConfReadyHooks(hooks ...Hook) {
@ -185,7 +190,7 @@ func RunConfHooks(c *cli.Context) {
for _, f := range ConfReadyHooks {
err := f(c)
if err != nil {
log.Fatalf("error running config hook: %v", err)
log.Fatalf("error running config hook: %v", err)
}
}
}

View File

@ -32,8 +32,8 @@ import (
)
const (
ConfigFileName = "config.toml"
ConfigDirName = "gosuki"
ConfigFileName = "config.toml"
ConfigDirName = "gosuki"
)
func getConfigDir() (string, error) {
@ -52,7 +52,7 @@ func getConfigDir() (string, error) {
func getConfigFile() (string, error) {
if configDir, err := getConfigDir(); err != nil {
return "", err
} else {
} else {
return path.Join(configDir, ConfigFileName), nil
}
}
@ -75,7 +75,6 @@ func ConfigExists() (bool, error) {
return utils.CheckFileExists(configFile)
}
// Create a toml config file
func InitConfigFile() error {
var configDir string
@ -108,6 +107,7 @@ func InitConfigFile() error {
return nil
}
// Loads gosuki configuation into the global config
func LoadFromTomlFile() error {
configFile, err := getConfigFile()
if err != nil {