firefox profiles loading, todo CLI

This commit is contained in:
Chakib Ben Ziane 2019-02-22 19:50:26 +01:00
parent 9ed35b4149
commit 0c069a3c39
10 changed files with 205 additions and 54 deletions

View File

@ -105,6 +105,7 @@ func (bw *BaseBrowser) GetWatcher() *Watcher {
} }
func (bw *BaseBrowser) Load() { func (bw *BaseBrowser) Load() {
log.Debug("BaseBrowser Load()") log.Debug("BaseBrowser Load()")
bw.InitIndex() bw.InitIndex()
// Check if cache is initialized // Check if cache is initialized

View File

@ -63,9 +63,16 @@ func startServer(c *cli.Context) {
// Initialize sqlite database available in global `cacheDB` variable // Initialize sqlite database available in global `cacheDB` variable
initDB() initDB()
browsers := []IBrowser{ var browsers []IBrowser
NewFFBrowser(),
NewChromeBrowser(), ff := NewFFBrowser()
if ff != nil {
browsers = append(browsers, ff)
}
cr := NewChromeBrowser()
if cr != nil {
browsers = append(browsers, cr)
} }
for _, b := range browsers { for _, b := range browsers {

View File

@ -4,6 +4,7 @@ package main
import ( import (
"database/sql" "database/sql"
"errors"
"gomark/database" "gomark/database"
"gomark/mozilla" "gomark/mozilla"
"gomark/parsing" "gomark/parsing"
@ -51,10 +52,15 @@ const (
ORDER BY url` ORDER BY url`
) )
var Firefox = BrowserPaths{ var (
BookmarkFile: mozilla.BookmarkFile, Firefox = BrowserPaths{
BookmarkDir: mozilla.BookmarkDir,
} BookmarkFile: mozilla.BookmarkFile,
BookmarkDir: mozilla.BookmarkDir,
}
ErrInitFirefox = errors.New("Could not start Firefox watcher")
)
const ( const (
MozMinJobInterval = 500 * time.Millisecond MozMinJobInterval = 500 * time.Millisecond
@ -136,6 +142,19 @@ func NewFFBrowser() IBrowser {
// Initialize `places.sqlite` // Initialize `places.sqlite`
bookmarkPath := path.Join(browser.baseDir, browser.bkFile) bookmarkPath := path.Join(browser.baseDir, browser.bkFile)
// Check if BookmarkPath exists
exists, err := utils.CheckFileExists(bookmarkPath)
if err != nil {
log.Critical(err)
log.Critical(ErrInitFirefox)
return nil
}
if !exists {
log.Criticalf("Bookmark path <%s> does not exist", bookmarkPath)
log.Critical(ErrInitFirefox)
return nil
}
opts := database.DsnOptions{ opts := database.DsnOptions{
"_journal_mode": "WAL", "_journal_mode": "WAL",
} }

View File

@ -4,11 +4,8 @@ import (
"gomark/logging" "gomark/logging"
) )
var fflog = logging.GetLogger("FF")
const ( const (
BookmarkFile = "places.sqlite" BookmarkFile = "places.sqlite"
BookmarkDir = "/home/spike/.mozilla/firefox/7otsk3vs.test_bookmarks"
) )
var ( var (
@ -16,5 +13,14 @@ var (
PlacesDSN = map[string]string{ PlacesDSN = map[string]string{
"_jouranl_mode": "WAL", "_jouranl_mode": "WAL",
} }
log = logging.GetLogger("MOZ")
log = logging.GetLogger("FF")
// Bookmark directory
BookmarkDir string
) )
func SetBookmarkDir(dir string) {
log.Debugf("setting bookmarks dir to <%s>", dir)
BookmarkDir = dir
}

View File

@ -1,6 +1,7 @@
package mozilla package mozilla
import ( import (
"errors"
"gomark/profiles" "gomark/profiles"
"gomark/utils" "gomark/utils"
"path/filepath" "path/filepath"
@ -9,6 +10,10 @@ import (
ini "gopkg.in/ini.v1" ini "gopkg.in/ini.v1"
) )
type ProfileManager = profiles.ProfileManager
type ProfileGetter = profiles.ProfileGetter
type PathGetter = profiles.PathGetter
const ( const (
ProfilesFile = "profiles.ini" ProfilesFile = "profiles.ini"
) )
@ -16,14 +21,40 @@ const (
var ( var (
ConfigFolder = ".mozilla/firefox" ConfigFolder = ".mozilla/firefox"
ReIniProfiles = regexp.MustCompile(`(?i)profile`) ReIniProfiles = regexp.MustCompile(`(?i)profile`)
firefoxProfile = &ProfileGetter{
//BasePath to be set at runtime in init
ProfilesFile: ProfilesFile,
}
FirefoxProfileManager = &FFProfileManager{
pathGetter: firefoxProfile,
}
ErrProfilesIni = errors.New("Could not parse Firefox profiles.ini file")
ErrNoDefaultProfile = errors.New("No default profile found")
) )
type FFProfileManager struct { type FFProfileManager struct {
basePath string
profilesFile *ini.File profilesFile *ini.File
pathGetter PathGetter
ProfileManager
}
func (pm *FFProfileManager) loadProfile() error {
log.Debugf("loading profile from <%s>", pm.pathGetter.Get())
pFile, err := ini.Load(pm.pathGetter.Get())
if err != nil {
return err
}
pm.profilesFile = pFile
return nil
} }
func (pm *FFProfileManager) GetProfiles() ([]*profiles.Profile, error) { func (pm *FFProfileManager) GetProfiles() ([]*profiles.Profile, error) {
pm.loadProfile()
sections := pm.profilesFile.Sections() sections := pm.profilesFile.Sections()
var filtered []*ini.Section var filtered []*ini.Section
var result []*profiles.Profile var result []*profiles.Profile
@ -48,7 +79,32 @@ func (pm *FFProfileManager) GetProfiles() ([]*profiles.Profile, error) {
return result, nil return result, nil
} }
func (pm *FFProfileManager) ListProfiles() []string { func (pm *FFProfileManager) GetDefaultProfilePath() (string, error) {
log.Debugf("using config dir %s", ConfigFolder)
p, err := pm.GetDefaultProfile()
if err != nil {
return "", err
}
return filepath.Join(ConfigFolder, p.Path), nil
}
func (pm *FFProfileManager) GetDefaultProfile() (*profiles.Profile, error) {
profs, err := pm.GetProfiles()
if err != nil {
return nil, err
}
for _, p := range profs {
if p.Name == "default" {
return p, nil
}
}
return nil, ErrNoDefaultProfile
}
func (pm *FFProfileManager) ListProfiles() ([]string, error) {
pm.loadProfile()
sections := pm.profilesFile.SectionStrings() sections := pm.profilesFile.SectionStrings()
var result []string var result []string
for _, s := range sections { for _, s := range sections {
@ -57,22 +113,11 @@ func (pm *FFProfileManager) ListProfiles() []string {
} }
} }
return result if len(result) == 0 {
} return nil, ErrProfilesIni
func NewFFProfileManager() (*FFProfileManager, error) {
profiles, err := ini.Load(filepath.Join(ConfigFolder, ProfilesFile))
if err != nil {
return nil, err
} }
pm := &FFProfileManager{ return result, nil
basePath: ConfigFolder,
profilesFile: profiles,
}
return pm, nil
} }
func init() { func init() {
@ -81,12 +126,21 @@ func init() {
// Check if base folder exists // Check if base folder exists
configFolderExists, err := utils.CheckDirExists(ConfigFolder) configFolderExists, err := utils.CheckDirExists(ConfigFolder)
if !configFolderExists { if !configFolderExists {
fflog.Criticalf("The base firefox folder <%s> does not exist", log.Criticalf("The base firefox folder <%s> does not exist",
ConfigFolder) ConfigFolder)
} }
if err != nil { if err != nil {
fflog.Critical(err) log.Critical(err)
} }
firefoxProfile.BasePath = ConfigFolder
bookmarkDir, err := FirefoxProfileManager.GetDefaultProfilePath()
if err != nil {
log.Error(err)
}
SetBookmarkDir(bookmarkDir)
} }

View File

@ -1,37 +1,64 @@
package mozilla package mozilla
import ( import (
"os"
"testing" "testing"
) )
func TestNewProfileManager(t *testing.T) { var OkProfile = &ProfileGetter{
InitialConfigFolder := ConfigFolder BasePath: "testdata",
ConfigFolder = "toto" ProfilesFile: "profiles_ok.ini",
_, err := NewFFProfileManager() }
if !os.IsNotExist(err) { var BadProfile = &ProfileGetter{
t.Error(err) BasePath: "testdata",
} ProfilesFile: "profiles_bad.ini",
ConfigFolder = InitialConfigFolder
} }
func TestListProfiles(t *testing.T) { func TestListProfiles(t *testing.T) {
pm, _ := NewFFProfileManager() //_, filename, _, _ := runtime.Caller(0)
//dir, err := filepath.Abs(filepath.Dir(filename))
//if err != nil {
//t.Error(err)
//}
//t.Error(dir)
t.Run("OK", func(t *testing.T) {
pm := &FFProfileManager{
pathGetter: OkProfile,
}
t.Log("Listing profiles")
profiles, err := pm.ListProfiles()
if err != nil {
t.Error(err)
}
for _, p := range profiles {
t.Logf("found profiles: %s", p)
}
if profiles[0] != "Profile0" {
t.Error("Expected Profile0")
}
})
t.Run("Bad", func(t *testing.T) {
pm := &FFProfileManager{
pathGetter: BadProfile,
}
_, err := pm.ListProfiles()
if err != ErrProfilesIni || err == nil {
t.Error("Expected error parsing bad profiles file")
}
})
t.Log("Listing profiles")
profiles := pm.ListProfiles()
for _, p := range pm.ListProfiles() {
t.Logf("found profiles: %s", p)
}
if profiles[0] != "Profile0" {
t.Error("Expected at least Profile0")
}
} }
func TestGetProfiles(t *testing.T) { func TestGetProfiles(t *testing.T) {
pm, _ := NewFFProfileManager() pm := &FFProfileManager{
pathGetter: OkProfile,
}
profs, err := pm.GetProfiles() profs, err := pm.GetProfiles()
if err != nil { if err != nil {
t.Error(err) t.Error(err)
@ -40,4 +67,8 @@ func TestGetProfiles(t *testing.T) {
for _, p := range profs { for _, p := range profs {
t.Log(p) t.Log(p)
} }
if profs[0].Name != "default" {
t.Error("Expected default profile in profiles.ini")
}
} }

View File

@ -52,13 +52,13 @@ func UnlockPlaces(dir string) error {
// TODO: #multiprocess add CLI to unlock places.sqlite // TODO: #multiprocess add CLI to unlock places.sqlite
pusers, err := utils.FileProcessUsers(path.Join(BookmarkDir, BookmarkFile)) pusers, err := utils.FileProcessUsers(path.Join(BookmarkDir, BookmarkFile))
if err != nil { if err != nil {
fflog.Error(err) log.Error(err)
} }
for pid, p := range pusers { for pid, p := range pusers {
pname, err := p.Name() pname, err := p.Name()
if err != nil { if err != nil {
fflog.Error(err) log.Error(err)
} }
return errors.New(fmt.Sprintf("multiprocess not enabled and %s(%d) is running. Close firefox and disable VFS lock", pname, pid)) return errors.New(fmt.Sprintf("multiprocess not enabled and %s(%d) is running. Close firefox and disable VFS lock", pname, pid))
} }

2
mozilla/testdata/profiles_bad.ini vendored Normal file
View File

@ -0,0 +1,2 @@
[Test]
Name=Does not contain a firefox profile

12
mozilla/testdata/profiles_ok.ini vendored Normal file
View File

@ -0,0 +1,12 @@
[General]
StartWithLastProfile=0
[Profile0]
Name=default
Path=path.default
[Profile1]
Name=profile1
Path=path.profile1

View File

@ -3,14 +3,16 @@
package profiles package profiles
import "path/filepath"
const ( const (
XDG_HOME = "XDG_CONFIG_HOME" XDG_HOME = "XDG_CONFIG_HOME"
) )
type ProfileManager interface { type ProfileManager interface {
ListProfiles() []string ListProfiles() ([]string, error)
GetProfiles() []*Profile GetProfiles() ([]*Profile, error)
GetDefaultProfile() Profile GetDefaultProfile() (*Profile, error)
} }
type Profile struct { type Profile struct {
@ -18,3 +20,20 @@ type Profile struct {
Name string Name string
Path string Path string
} }
func (p *Profile) GetPath() string {
return p.Path
}
type PathGetter interface {
Get() string
}
type ProfileGetter struct {
BasePath string
ProfilesFile string
}
func (pg *ProfileGetter) Get() string {
return filepath.Join(pg.BasePath, pg.ProfilesFile)
}