package bookmark
import (
"database/sql"
"os"
"sort"
"time"
// import sqlite3 driver
_ "github.com/mattn/go-sqlite3"
"github.com/tidwall/gjson"
"github.com/moond4rk/hackbrowserdata/item"
"github.com/moond4rk/hackbrowserdata/log"
"github.com/moond4rk/hackbrowserdata/utils/fileutil"
"github.com/moond4rk/hackbrowserdata/utils/typeutil"
)
type ChromiumBookmark [ ] bookmark
type bookmark struct {
ID int64
Name string
Type string
URL string
DateAdded time . Time
}
func ( c * ChromiumBookmark ) Parse ( _ [ ] byte ) error {
bookmarks , err := fileutil . ReadFile ( item . TempChromiumBookmark )
if err != nil {
return err
}
defer os . Remove ( item . TempChromiumBookmark )
r := gjson . Parse ( bookmarks )
if r . Exists ( ) {
roots := r . Get ( "roots" )
roots . ForEach ( func ( key , value gjson . Result ) bool {
getBookmarkChildren ( value , c )
return true
} )
}
sort . Slice ( * c , func ( i , j int ) bool {
return ( * c ) [ i ] . DateAdded . After ( ( * c ) [ j ] . DateAdded )
} )
return nil
}
const (
bookmarkID = "id"
bookmarkAdded = "date_added"
bookmarkURL = "url"
bookmarkName = "name"
bookmarkType = "type"
bookmarkChildren = "children"
)
func getBookmarkChildren ( value gjson . Result , w * ChromiumBookmark ) ( children gjson . Result ) {
nodeType := value . Get ( bookmarkType )
children = value . Get ( bookmarkChildren )
bm := bookmark {
ID : value . Get ( bookmarkID ) . Int ( ) ,
Name : value . Get ( bookmarkName ) . String ( ) ,
URL : value . Get ( bookmarkURL ) . String ( ) ,
DateAdded : typeutil . TimeEpoch ( value . Get ( bookmarkAdded ) . Int ( ) ) ,
}
if nodeType . Exists ( ) {
bm . Type = nodeType . String ( )
* w = append ( * w , bm )
if children . Exists ( ) && children . IsArray ( ) {
for _ , v := range children . Array ( ) {
children = getBookmarkChildren ( v , w )
}
}
}
return children
}
func ( c * ChromiumBookmark ) Name ( ) string {
return "bookmark"
}
func ( c * ChromiumBookmark ) Len ( ) int {
return len ( * c )
}
type FirefoxBookmark [ ] bookmark
const (
queryFirefoxBookMark = ` SELECT id, url, type, dateAdded, title FROM (SELECT * FROM moz_bookmarks INNER JOIN moz_places ON moz_bookmarks.fk=moz_places.id) `
closeJournalMode = ` PRAGMA journal_mode=off `
)
func ( f * FirefoxBookmark ) Parse ( _ [ ] byte ) error {
db , err := sql . Open ( "sqlite3" , item . TempFirefoxBookmark )
if err != nil {
return err
}
defer os . Remove ( item . TempFirefoxBookmark )
defer db . Close ( )
_ , err = db . Exec ( closeJournalMode )
if err != nil {
log . Error ( err )
}
rows , err := db . Query ( queryFirefoxBookMark )
if err != nil {
return err
}
defer rows . Close ( )
for rows . Next ( ) {
var (
id , bt , dateAdded int64
title , url string
)
if err = rows . Scan ( & id , & url , & bt , & dateAdded , & title ) ; err != nil {
log . Warn ( err )
}
* f = append ( * f , bookmark {
ID : id ,
Name : title ,
Type : linkType ( bt ) ,
URL : url ,
DateAdded : typeutil . TimeStamp ( dateAdded / 1000000 ) ,
} )
}
sort . Slice ( * f , func ( i , j int ) bool {
return ( * f ) [ i ] . DateAdded . After ( ( * f ) [ j ] . DateAdded )
} )
return nil
}
func ( f * FirefoxBookmark ) Name ( ) string {
return "bookmark"
}
func ( f * FirefoxBookmark ) Len ( ) int {
return len ( * f )
}
func linkType ( a int64 ) string {
switch a {
case 1 :
return "url"
default :
return "folder"
}
}