diff --git a/TODO b/TODO index 3525d2f..8389e32 100644 --- 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) diff --git a/library/database.py b/library/database.py index 0940ba6..9da5950 100644 --- a/library/database.py +++ b/library/database.py @@ -268,6 +268,22 @@ def categorizeBook(book, cats): conn.commit() 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) @@ -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 index 0000000..a9cee10 Binary files /dev/null and b/library/interface/.browser.py.swp differ diff --git a/library/interface/browser.py b/library/interface/browser.py index d3e380b..93d6577 100644 --- a/library/interface/browser.py +++ b/library/interface/browser.py @@ -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)]