Categorizing and uncategorizing based on selection

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.
This commit is contained in:
Felix Bauckholt 2016-03-12 20:58:51 -05:00
parent f299412d56
commit 3487b66393
4 changed files with 97 additions and 8 deletions

4
TODO
View File

@ -1,8 +1,5 @@
_List of Desired Features_ _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 Regex Search
Choose shown columns in browser Choose shown columns in browser
Support for multiple copies Support for multiple copies
@ -33,6 +30,7 @@ Error checking out an already checked out book
_Implemented Features_ _Implemented Features_
Categories work based on selection, not just highlight
Sort by column in browser Sort by column in browser
Support UTF-8 for everything Support UTF-8 for everything
Search ignores Case (for lowercase search strings) Search ignores Case (for lowercase search strings)

View File

@ -268,6 +268,22 @@ def categorizeBook(book, cats):
conn.commit() conn.commit()
c.close() 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) @permissions.check_permissions(permissions.PERMISSION_LIBCOM)
def uncategorizeBook(book, cats): def uncategorizeBook(book, cats):
conn = sqlite3.connect(_catalogue_db_file) conn = sqlite3.connect(_catalogue_db_file)
@ -279,6 +295,17 @@ def uncategorizeBook(book, cats):
conn.commit() conn.commit()
c.close() 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(): def getCategories():
conn = sqlite3.connect(_catalogue_db_file) conn = sqlite3.connect(_catalogue_db_file)
c = conn.cursor() c = conn.cursor()

Binary file not shown.

View File

@ -336,7 +336,7 @@ class bookBrowser(browserWindow):
('Authors',30,None), ('Authors',30,None),
('Title',60,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 # redefinable functions
@ -380,12 +380,28 @@ class bookBrowser(browserWindow):
books.append(book) books.append(book)
db.removeBooks(books) 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): def refreshBooks(self):
self.load_data(db.get_books()) self.load_data(db.get_books())
def refreshBooksInCategory(self,cat): #def refreshBooksInCategory(self,cat):
self.refreshBooks = lambda : self.load_data(db.getBooksByCategory(cat)) # self.refreshBooks = lambda : self.load_data(db.getBooksByCategory(cat))
self.refreshBooks() # self.refreshBooks()
def refreshBooksUncategorized(self): def refreshBooksUncategorized(self):
self.refreshBooks = lambda : self.load_data(db.getUncategorizedBooks()) self.refreshBooks = lambda : self.load_data(db.getUncategorizedBooks())
@ -415,6 +431,9 @@ class bookBrowser(browserWindow):
book = self.highlightedEntry() book = self.highlightedEntry()
self.categorizeSelection(book) self.categorizeSelection(book)
self.refresh() self.refresh()
elif ch == 97: #a
self.addBooksToCategory()
self.refresh()
if ch == 100: if ch == 100:
count=0 count=0
for s in self.selected[0:self.hl-1]: for s in self.selected[0:self.hl-1]:
@ -427,6 +446,30 @@ class bookBrowser(browserWindow):
self.mvHighlight(-count) self.mvHighlight(-count)
return ch 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): class categoryBrowser(browserWindow):
columnDefs = [('Category',100,None)] columnDefs = [('Category',100,None)]
cs = [(' a', 'add category'), (' d', 'delete selected')] cs = [(' a', 'add category'), (' d', 'delete selected')]
@ -446,7 +489,7 @@ class categoryBrowser(browserWindow):
def viewCategory(self): def viewCategory(self):
w = curses.newwin(3,5) w = curses.newwin(3,5)
b = bookBrowser(w,self.hb) b = bookBrowserInCategory(w,self.hb)
self.centreChild(w) self.centreChild(w)
b.refreshBooksInCategory(self.highlightedEntry()) b.refreshBooksInCategory(self.highlightedEntry())
b.eventLoop() b.eventLoop()
@ -545,6 +588,27 @@ class categorySelector(browserWindow):
return 113 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): class columnSelector(browserWindow):
columnDefs = [('Column',100,None)] columnDefs = [('Column',100,None)]