Categorizing and uncategorizing based on selection
authorFelix Bauckholt <felixbauckholt@gmail.com>
Sun, 13 Mar 2016 01:58:51 +0000 (20:58 -0500)
committerFelix Bauckholt <felixbauckholt@gmail.com>
Sun, 13 Mar 2016 02:02:43 +0000 (21:02 -0500)
Now, in any book browser window, you can add every
selected book to one category.

When you are browsing the books in a category, you
can remove every selected book from that category.

TODO
library/database.py
library/interface/.browser.py.swp [new file with mode: 0644]
library/interface/browser.py

diff --git a/TODO b/TODO
index 3525d2f..8389e32 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,8 +1,5 @@
 _List of Desired Features_
 
-Categories work based on selection, not just highlight
- - i.e. assign categories to multiple books at once
- - this may involve extra logic if books don't have the same categories beforehand
 Regex Search
 Choose shown columns in browser
 Support for multiple copies
@@ -33,6 +30,7 @@ Error checking out an already checked out book
 
 
 _Implemented Features_
+Categories work based on selection, not just highlight
 Sort by column in browser
 Support UTF-8 for everything
 Search ignores Case (for lowercase search strings)
index 0940ba6..9da5950 100644 (file)
@@ -269,6 +269,22 @@ def categorizeBook(book, cats):
     c.close()
 
 @permissions.check_permissions(permissions.PERMISSION_LIBCOM)
+def categorizeBooks(cat, books):
+    conn = sqlite3.connect(_catalogue_db_file)
+    c = conn.cursor()
+    query = ("INSERT OR IGNORE INTO "+_book_category_table+
+             " (id,cat_id) VALUES (?, ?);")
+    exists_query = "SELECT * FROM "+_book_category_table+" WHERE (id = ? AND cat_id = ?);"
+    for book in books:
+        args = (book['id'],cat['id'])
+        c.execute(exists_query, args)
+        if len(c.fetchall()) == 0:
+            c.execute(query,args)
+    conn.commit()
+    c.close()
+
+
+@permissions.check_permissions(permissions.PERMISSION_LIBCOM)
 def uncategorizeBook(book, cats):
     conn = sqlite3.connect(_catalogue_db_file)
     c = conn.cursor()
@@ -279,6 +295,17 @@ def uncategorizeBook(book, cats):
     conn.commit()
     c.close()
 
+@permissions.check_permissions(permissions.PERMISSION_LIBCOM)
+def uncategorizeBooks(books, cat):
+    conn = sqlite3.connect(_catalogue_db_file)
+    c = conn.cursor()
+    query = "DELETE FROM "+_book_category_table+" WHERE (id = ? AND cat_id = ?);"
+    for book in books:
+        args = (book['id'],cat['id'])
+        c.execute(query,args)
+    conn.commit()
+    c.close()
+
 def getCategories():
     conn = sqlite3.connect(_catalogue_db_file)
     c = conn.cursor()
diff --git a/library/interface/.browser.py.swp b/library/interface/.browser.py.swp
new file mode 100644 (file)
index 0000000..a9cee10
Binary files /dev/null and b/library/interface/.browser.py.swp differ
index d3e380b..93d6577 100644 (file)
@@ -336,7 +336,7 @@ class bookBrowser(browserWindow):
                   ('Authors',30,None),
                   ('Title',60,None)]
 
-    cs = [(' u', 'update'), (' d', 'delete selected'), (' c', 'categorize')]
+    cs = [(' u', 'update'), (' d', 'delete selected'), (' c', 'categorize'), (' a', 'add selected to category')]
 
 
     # redefinable functions
@@ -380,12 +380,28 @@ class bookBrowser(browserWindow):
                 books.append(book)
         db.removeBooks(books)
 
+    @catch_error
+    def addBooksToCategory(self):
+        books = []
+        for sel,book in zip(self.selected, self.entries):
+            if sel:
+                books.append(book)
+        w = curses.newwin(1,1)
+        cs = singleCategorySelector(w,self.hb,40,50)
+        self.centreChild(w)
+        cs.refreshCategories()
+        cat = cs.eventLoop()
+        cs.clear()
+        self.refreshBooks()
+        if cat:
+            db.categorizeBooks(cat, books)
+
     def refreshBooks(self):
         self.load_data(db.get_books())
 
-    def refreshBooksInCategory(self,cat):
-        self.refreshBooks = lambda : self.load_data(db.getBooksByCategory(cat))
-        self.refreshBooks()
+    #def refreshBooksInCategory(self,cat):
+    #    self.refreshBooks = lambda : self.load_data(db.getBooksByCategory(cat))
+    #    self.refreshBooks()
 
     def refreshBooksUncategorized(self):
         self.refreshBooks = lambda : self.load_data(db.getUncategorizedBooks())
@@ -415,6 +431,9 @@ class bookBrowser(browserWindow):
             book = self.highlightedEntry()
             self.categorizeSelection(book)
             self.refresh()
+        elif ch == 97: #a
+            self.addBooksToCategory()
+            self.refresh()
         if ch == 100:
             count=0
             for s in self.selected[0:self.hl-1]:
@@ -427,6 +446,30 @@ class bookBrowser(browserWindow):
             self.mvHighlight(-count)
         return ch
 
+#a pretty ugly hack in order to be able to remove books from this category
+class bookBrowserInCategory(bookBrowser):
+    cs = [(' u', 'update'), (' d', 'delete selected'), (' c', 'categorize'), (' a', 'add selected to category'), (' r', 'uncategorize selected')]
+
+    def refreshBooksInCategory(self,cat):
+        self.cat = cat
+        self.refreshBooks = lambda : self.load_data(db.getBooksByCategory(cat))
+        self.refreshBooks()
+
+    @catch_error
+    def uncategorizeBooks(self):
+        books = []
+        for sel,book in zip(self.selected, self.entries):
+            if sel:
+                books.append(book)
+        db.uncategorizeBooks(books, self.cat)
+
+    def handleInput(self,ch):
+        if ch == 114: #r
+            self.uncategorizeBooks()
+            self.refreshBooks()
+            self.refresh()
+        bookBrowser.handleInput(self,ch)
+
 class categoryBrowser(browserWindow):
     columnDefs = [('Category',100,None)]
     cs = [(' a', 'add category'), (' d', 'delete selected')]
@@ -446,7 +489,7 @@ class categoryBrowser(browserWindow):
 
     def viewCategory(self):
         w = curses.newwin(3,5)
-        b = bookBrowser(w,self.hb)
+        b = bookBrowserInCategory(w,self.hb)
         self.centreChild(w)
         b.refreshBooksInCategory(self.highlightedEntry())
         b.eventLoop()
@@ -545,6 +588,27 @@ class categorySelector(browserWindow):
             return 113
 
 
+class singleCategorySelector(categorySelector):
+    columnDefs = [('Category',100,None)]
+    cs = []
+    commands = [(' /', 'search'), (' n', 'find next'), (' N', 'find previous'),
+                (' q', 'quit'), ('Enter', 'done')]
+
+    def handleInput(self,ch):
+        return browserWindow.handleInput(self,ch,True)
+
+    def eventLoop(self):
+        self.w.keypad(1)
+        self.refresh()
+
+        ch = self.w.getch()
+        while ch != 27 and ch != 113:
+            if ch == 10:
+                return self.highlightedEntry()
+            self.handleInput(ch)
+            self.w.refresh()
+            ch = self.w.getch()
+            self.hb.refresh()
 
 class columnSelector(browserWindow):
     columnDefs = [('Column',100,None)]