diff --git a/cmd/ftrove/main.go b/cmd/ftrove/main.go index 791da7a2..11af4495 100644 --- a/cmd/ftrove/main.go +++ b/cmd/ftrove/main.go @@ -48,6 +48,7 @@ func main() { inDir := flag.StringP("indir", "i", "", "Input directory to work on.") install := flag.StringP("install", "", "", "Install FileTrove into the given, existing directory.") listSessions := flag.BoolP("list-sessions", "l", false, "List session information for all scans. Useful for exports.") + listSession := flag.StringP("list-session", "L", "", "List information about a single session.") projectname := flag.StringP("project", "p", "", "A name for the project or scan session.") resumeuuid := flag.StringP("resume", "r", "", "Resume an aborted session. Provide the session uuid.") timezone := flag.StringP("timezone", "z", "", "Set the time zone to a region in which the timestamps of files are to be translated. If this flag is not set, the local time zone is used. Example: Europe/Berlin") @@ -149,6 +150,24 @@ func main() { return } + // Print info about a single session + if len(*listSession) > 0 { + fmt.Println("SESSION INFORMATION\n") + smd, err := ft.ListSession(ftdb, *listSession) + if err != nil { + logger.Error("Could not query single session.", slog.String("error", err.Error())) + } + + fmt.Println("Session UUID:\t" + smd.Sessionmd.UUID) + fmt.Println("Project:\t" + smd.Sessionmd.Project) + fmt.Println("Archivist:\t" + smd.Sessionmd.Archivistname) + fmt.Println("Mountpoint:\t" + smd.Sessionmd.Mountpoint) + fmt.Println("File Count:\t" + strconv.Itoa(smd.Filecount)) + fmt.Println("NSRL Count:\t" + strconv.Itoa(smd.Nsrlcount)) + + return + } + // Check if ready for run. err = ft.CheckInstall(Version) if err != nil { diff --git a/database_schema.dbml b/database_schema.dbml index 813e682a..9fe1bd95 100644 --- a/database_schema.dbml +++ b/database_schema.dbml @@ -43,6 +43,9 @@ TABLE dublincore{ TABLE files {fileuuid TEXT sessionuuid TEXT filename TEXT + filepath TEXT + filepath TEXT + filenameextension TEXT filesize INTEGER filemd5 TEXT filesha1 TEXT @@ -67,6 +70,10 @@ TABLE directories{ diruuid TEXT sessionuuid TEXT dirname TEXT + dirpath TEXT + dirctime TEXT + dirmtime TEXT + diratime TEXT hierarchy INTEGER } diff --git a/db.go b/db.go index 901fbef3..0d4ddd00 100644 --- a/db.go +++ b/db.go @@ -33,6 +33,19 @@ type SessionMD struct { Goversion string } +// SessionInfo holds information about a single session +type SessionInfoMD struct { + Sessionmd SessionMD + Rowid string + Filecount int + Oldestfile string + Oldestfiledate string + Youngestfile string + Youngestfiledate string + Nsrlcount int + Difffiletypes int +} + // FileMD holds the metadata for each inspected file and that is written to the table files type FileMD struct { Filename string @@ -247,6 +260,7 @@ func ListSessions(db *sql.DB) error { if err := rows.Scan(&rowid, &uuid, &starttime, &endtime, &project, &archivistname, &mountpoint); err != nil { return err } + fmt.Fprintln(w, rowid+"\t"+uuid+"\t"+starttime+"\t"+endtime+"\t"+project+"\t"+archivistname+"\t"+mountpoint) } w.Flush() @@ -254,6 +268,51 @@ func ListSessions(db *sql.DB) error { return err } +// ListSession returns information summary about a single session +func ListSession(db *sql.DB, sessionuuid string) (SessionInfoMD, error) { + var smd SessionInfoMD + // Prepare project query + sessionquery, err := db.Prepare("SELECT rowid, uuid, starttime, COALESCE(endtime, '') AS endtime, " + + "COALESCE(project, '') AS project, " + + "COALESCE(archivistname,'') AS archivistname, " + + "COALESCE(mountpoint,'') AS mountpoint FROM sessionsmd WHERE uuid=?") + if err != nil { + return smd, err + } + + sessionrow := sessionquery.QueryRow(sessionuuid) + + if err := sessionrow.Scan(&smd.Rowid, + &smd.Sessionmd.UUID, + &smd.Sessionmd.Starttime, + &smd.Sessionmd.Endtime, + &smd.Sessionmd.Project, + &smd.Sessionmd.Archivistname, + &smd.Sessionmd.Mountpoint); err != nil { + return smd, err + } + + filesquery, err := db.Prepare("SELECT COUNT(filename) FROM files WHERE sessionuuid=?") + if err != nil { + return smd, err + } + filerows := filesquery.QueryRow(sessionuuid) + if err = filerows.Scan(&smd.Filecount); err != nil { + return smd, err + } + + nsrlquery, err := db.Prepare("SELECT COUNT(filename) FROM files WHERE sessionuuid=? AND filensrl='TRUE'") + if err != nil { + return smd, err + } + nsrlrows := nsrlquery.QueryRow(sessionuuid) + if err = nsrlrows.Scan(&smd.Nsrlcount); err != nil { + return smd, err + } + + return smd, err +} + // ExportSessionSessionTSV exports all session metadata from a session to a TSV file. // Filtering is done by session UUID. func ExportSessionSessionTSV(sessionuuid string) ([]string, error) { @@ -716,7 +775,3 @@ func ResumeLatestEntry(db *sql.DB, sessionuuid string) (ResumeInfo, error) { return ri, err } - -func GetSessionInfo(db *sql.DB, sessionuuid string) (SessionInfo, error) { - -}