diff --git a/internal/browser/browser.go b/internal/browser/browser.go index 0cc1b8d..402a298 100644 --- a/internal/browser/browser.go +++ b/internal/browser/browser.go @@ -46,9 +46,12 @@ func pickChromium(name, profile string) []Browser { log.Noticef("find browser %s failed, profile folder does not exist", v.name) continue } - if b, err := chromium.New(v.name, v.storage, v.profilePath, v.items); err == nil { - log.Noticef("find browser %s success", b.Name()) - browsers = append(browsers, b) + if multiChromium, err := chromium.New(v.name, v.storage, v.profilePath, v.items); err == nil { + log.Noticef("find browser %s success", v.name) + for _, b := range multiChromium { + log.Noticef("find browser %s success", b.Name()) + browsers = append(browsers, b) + } } else { log.Errorf("new chromium error: %s", err.Error()) } @@ -61,12 +64,14 @@ func pickChromium(name, profile string) []Browser { if !fileutil.FolderExists(filepath.Clean(profile)) { log.Fatalf("find browser %s failed, profile folder does not exist", c.name) } - b, err := chromium.New(c.name, c.storage, profile, c.items) + chromiumList, err := chromium.New(c.name, c.storage, profile, c.items) if err != nil { - log.Fatalf("new chromium error:", err) + log.Fatalf("new chromium error: %s", err) + } + for _, b := range chromiumList { + log.Noticef("find browser %s success", b.Name()) + browsers = append(browsers, b) } - log.Noticef("find browser %s success", b.Name()) - browsers = append(browsers, b) } return browsers } diff --git a/internal/browser/browser_windows.go b/internal/browser/browser_windows.go index 72e90c2..81ed864 100644 --- a/internal/browser/browser_windows.go +++ b/internal/browser/browser_windows.go @@ -3,9 +3,10 @@ package browser import ( - "hack-browser-data/internal/item" "io/ioutil" "os" + + "hack-browser-data/internal/item" ) var ( diff --git a/internal/browser/chromium/chromium.go b/internal/browser/chromium/chromium.go index bd06594..1babd89 100644 --- a/internal/browser/chromium/chromium.go +++ b/internal/browser/chromium/chromium.go @@ -1,6 +1,7 @@ package chromium import ( + "io/fs" "os" "path/filepath" "strings" @@ -21,19 +22,26 @@ type chromium struct { } // New create instance of chromium browser, fill item's path if item is existed. -func New(name, storage, profilePath string, items []item.Item) (*chromium, error) { +func New(name, storage, profilePath string, items []item.Item) ([]*chromium, error) { c := &chromium{ - name: name, - storage: storage, + name: name, + storage: storage, + profilePath: profilePath, + items: items, } - itemsPaths, err := c.getItemPath(profilePath, items) + multiItemPaths, err := c.getMultiItemPath(c.profilePath, c.items) if err != nil { return nil, err } - c.profilePath = profilePath - c.itemPaths = itemsPaths - c.items = typeutil.Keys(itemsPaths) - return c, err + var chromiumList []*chromium + for user, itemPaths := range multiItemPaths { + chromiumList = append(chromiumList, &chromium{ + name: fileutil.BrowserName(name, user), + items: typeutil.Keys(itemPaths), + itemPaths: itemPaths, + }) + } + return chromiumList, nil } func (c *chromium) Name() string { @@ -93,6 +101,54 @@ func (c *chromium) getItemPath(profilePath string, items []item.Item) (map[item. return itemPaths, nil } +func (c *chromium) getMultiItemPath(profilePath string, items []item.Item) (map[string]map[item.Item]string, error) { + var multiItemPaths = make(map[string]map[item.Item]string) + parentDir := fileutil.ParentDir(profilePath) + err := filepath.Walk(parentDir, chromiumWalkFunc2(items, multiItemPaths)) + if err != nil { + return nil, err + } + var keyPath string + var dir string + for userDir, v := range multiItemPaths { + for _, p := range v { + if strings.HasSuffix(p, item.ChromiumKey.FileName()) { + keyPath = p + dir = userDir + break + } + } + } + t := make(map[string]map[item.Item]string) + for userDir, v := range multiItemPaths { + if userDir == dir { + continue + } + t[userDir] = v + t[userDir][item.ChromiumKey] = keyPath + } + return t, nil +} + +func chromiumWalkFunc2(items []item.Item, multiItemPaths map[string]map[item.Item]string) filepath.WalkFunc { + return func(path string, info fs.FileInfo, err error) error { + for _, v := range items { + if info.Name() == v.FileName() { + parentBaseDir := fileutil.ParentBaseDir(path) + if parentBaseDir == "System Profile" { + continue + } + if _, exist := multiItemPaths[parentBaseDir]; exist { + multiItemPaths[parentBaseDir][v] = path + } else { + multiItemPaths[parentBaseDir] = map[item.Item]string{v: path} + } + } + } + return err + } +} + func chromiumWalkFunc(items []item.Item, itemPaths map[item.Item]string, baseDir string) filepath.WalkFunc { return func(path string, info os.FileInfo, err error) error { for _, it := range items { diff --git a/internal/utils/fileutil/filetutil.go b/internal/utils/fileutil/filetutil.go index 9f801fa..eb357a1 100644 --- a/internal/utils/fileutil/filetutil.go +++ b/internal/utils/fileutil/filetutil.go @@ -115,6 +115,11 @@ func Filename(browser, item, ext string) string { return strings.ToLower(fmt.Sprintf("%s_%s.%s", replace.Replace(browser), item, ext)) } +func BrowserName(browser, user string) string { + replace := strings.NewReplacer(" ", "_", ".", "_", "-", "_", "Profile", "User") + return strings.ToLower(fmt.Sprintf("%s_%s", replace.Replace(browser), replace.Replace(user))) +} + // ParentDir returns the parent directory of the provided path func ParentDir(p string) string { return filepath.Dir(filepath.Clean(p))