func CreateObject(c *cli.Context) { title := strings.Join(c.Args(), " ") object := data.CreateObject(title) err := data.Objects().Insert(object) helper.ErrPanic(err) fmt.Printf("%s\n", object.Id.Hex()) }
func Search(c *cli.Context) { colors.Allow(c) page := c.Int("page") perPage := 10 searchQuery := data.ParseQuery(c.Args()) search := []bson.M{} if searchQuery.Text != "" { search = append(search, bson.M{ "$text": bson.M{ "$search": searchQuery.Text, }, }) } for _, attrQuery := range searchQuery.AttributeQuery { search = append(search, bson.M{ "attributes": bson.M{ "$elemMatch": bson.M{ "name": attrQuery.Name, "value": bson.M{ "$regex": attrQuery.Value, }, }, }, }) } query := data.Objects().Find(bson.M{ "$and": search, }).Select(bson.M{ "score": bson.M{ "$meta": "textScore", }, }).Sort("$textScore:score", "-_id") total, _ := query.Count() result := []data.SearchObject{} query.Skip((page - 1) * perPage).Limit(perPage).All(&result) if total > 0 { data.ClearCache() defer data.FlushCache() for index, object := range result { fmt.Printf("(%s) %s \"%s\" %s\n", colors.ShortId(index+1), colors.ObjectId(object.Id.Hex()), object.Title, colors.Faint(fmt.Sprintf("[%.2f]", object.Score))) data.SetCache(strconv.Itoa(index+1), object.Id.Hex()) } fmt.Printf("Page %s of %s\n", colors.Bold(strconv.Itoa(page)), colors.Bold(strconv.Itoa(int(total/perPage)+1))) } }
func DeleteObject(c *cli.Context) { objectId := helper.ValidId(c.Args().First()) object, err := data.GetObject(objectId) helper.ErrExit(err != nil, fmt.Sprintf("Invalid object ID %s!\n", objectId)) files := data.Files() for _, attachment := range object.Attachments { files.RemoveId(attachment.Id) } data.Objects().RemoveId(object.Id) }
func DeleteAttachment(c *cli.Context) { objectId := helper.ValidId(c.Args().First()) err := data.Files().RemoveId(bson.ObjectIdHex(objectId)) helper.ErrPanic(err) query := data.Objects().Find(bson.M{ "attachments._id": bson.ObjectIdHex(objectId), }) result := []data.Object{} query.All(&result) for _, object := range result { object.RemoveAttachment(objectId) } }
func GetObjects(c *cli.Context) { colors.Allow(c) query := data.Objects().Find(nil).Sort("-_id") page := c.Int("page") perPage := 10 total, _ := query.Count() result := []data.Object{} query.Skip((page - 1) * perPage).Limit(perPage).All(&result) if total > 0 { data.ClearCache() defer data.FlushCache() for index, object := range result { fmt.Printf("(%s) %s \"%s\"\n", colors.ShortId(index+1), colors.ObjectId(object.Id.Hex()), object.Title) data.SetCache(strconv.Itoa(index+1), object.Id.Hex()) } fmt.Printf("Page %s of %s\n", colors.Bold(strconv.Itoa(page)), colors.Bold(strconv.Itoa(int(total/perPage)+1))) } }
func main() { app := cli.NewApp() app.EnableBashCompletion = true app.Name = "shelf" app.Usage = "a simple document management system" app.Flags = []cli.Flag{ cli.BoolFlag{ Name: "no-color", Usage: "disable colored output", }, } app.Commands = []cli.Command{ { Name: "create", Usage: "create an document", Action: actions.CreateObject, }, { Name: "delete", Usage: "deletes an document", Action: actions.DeleteObject, }, { Name: "list", Usage: "lists documents", Action: actions.GetObjects, Flags: []cli.Flag{ cli.IntFlag{ Name: "page", Value: 1, Usage: "results page", }, }, }, { Name: "info", Usage: "print information about an document or attachment", Action: actions.GetInfo, }, { Name: "attach", Usage: "attach a file to an document", Action: actions.AddAttachment, Flags: []cli.Flag{ cli.BoolTFlag{ Name: "extract-pdf-text", Usage: "try to extract text from pdf, relies on pdftotext (poppler/poppler-utils)", EnvVar: "SHELF_EXTRACT_PDF_TEXT", }, }, }, { Name: "detach", Usage: "remove a file from an document", Action: actions.DeleteAttachment, }, { Name: "attachments", Usage: "list all attachments of an document", Action: actions.ListAttachments, }, { Name: "retrieve", Usage: "send an attachment to stdout", Action: actions.GetAttachment, }, { Name: "attribute", Usage: "manage document attributes", Subcommands: []cli.Command{ { Name: "add", Usage: "add an attribute to an document", Action: actions.AddAttribute, }, { Name: "remove", Usage: "remove an attribute from an document", Action: actions.RemoveAttribute, }, }, }, { Name: "tag", Usage: "add a tag to an document", Action: actions.AddTag, }, { Name: "untag", Usage: "remove a tag from an document", Action: actions.RemoveTag, }, { Name: "search", Usage: "search documents", Action: actions.Search, Flags: []cli.Flag{ cli.IntFlag{ Name: "page", Value: 1, Usage: "search results page", }, }, }, } _, session := data.DB() defer session.Close() data.Objects().EnsureIndex(mgo.Index{ Key: []string{ "$text:title", "$text:attachments.content", "$text:attachments.metadata.value", "$text:attributes.value", }, Weights: map[string]int{ "title": 10, "attributes.value": 8, "attachments.metadata.value": 8, "attachments.content": 5, }, }) app.Run(os.Args) }