From ce22a0da008bd4e249eac79b73d03c34da37df49 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 25 Jan 2018 15:13:48 +0530 Subject: [PATCH] AJAX endpoint for deleting books from server --- src/calibre/srv/cdb.py | 17 ++++++++++++++++- src/calibre/srv/tests/ajax.py | 17 +++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/calibre/srv/cdb.py b/src/calibre/srv/cdb.py index 473421f8ff..a430801464 100644 --- a/src/calibre/srv/cdb.py +++ b/src/calibre/srv/cdb.py @@ -11,7 +11,7 @@ from io import BytesIO from calibre import as_unicode, sanitize_file_name_unicode from calibre.db.cli import module_for_cmd from calibre.ebooks.metadata.meta import get_metadata -from calibre.srv.changes import books_added +from calibre.srv.changes import books_added, books_deleted from calibre.srv.errors import HTTPBadRequest, HTTPForbidden, HTTPNotFound from calibre.srv.routes import endpoint, json, msgpack_or_json from calibre.srv.utils import get_db, get_library_data @@ -91,3 +91,18 @@ def cdb_add_book(ctx, rd, job_id, add_duplicates, filename, library_id): ans['book_id'] = ids[0] books_added(ids) return ans + + +@endpoint('/cdb/delete-books/{book_ids}/{library_id=None}', + needs_db_write=True, postprocess=json, methods=receive_data_methods, cache_control='no-cache') +def cdb_delete_book(ctx, rd, book_ids, library_id): + db = get_db(ctx, rd, library_id) + if ctx.restriction_for(rd, db): + raise HTTPForbidden('Cannot use the delete book interface with a user who has per library restrictions') + try: + ids = {int(x) for x in book_ids.split(',')} + except Exception: + raise HTTPBadRequest('invalid book_ids: {}'.format(book_ids)) + db.remove_books(ids) + books_deleted(ids) + return {} diff --git a/src/calibre/srv/tests/ajax.py b/src/calibre/srv/tests/ajax.py index 7045b3f69b..759e715775 100644 --- a/src/calibre/srv/tests/ajax.py +++ b/src/calibre/srv/tests/ajax.py @@ -139,6 +139,7 @@ class ContentTest(LibraryBaseTest): # cdb.py r(url_for('/cdb/cmd', which='list'), status=FORBIDDEN) r(url_for('/cdb/add-book', job_id=1, add_duplicates='n', filename='test.epub'), status=FORBIDDEN) + r(url_for('/cdb/delete-books', book_ids='1'), status=FORBIDDEN) # code.py def sr(path, **k): @@ -165,16 +166,23 @@ class ContentTest(LibraryBaseTest): ae = self.assertEqual - def r(filename, data=None, status=OK, method='POST', username='12', add_duplicates='n', job_id=1): + def a(filename, data=None, status=OK, method='POST', username='12', add_duplicates='n', job_id=1): r, data = make_request(conn, '/cdb/add-book/{}/{}/{}'.format(job_id, add_duplicates, quote(filename.encode('utf-8')).decode('ascii')), username=username, password='test', prefix='', method=method, data=data) ae(status, r.status) return data - r('test.epub', None, username='ro', status=FORBIDDEN) + def d(book_ids, username='12', status=OK): + book_ids = ','.join(map(str, book_ids)) + r, data = make_request(conn, '/cdb/delete-books/{}'.format(book_ids), + username=username, password='test', prefix='', method='POST') + ae(status, r.status) + return data + + a('test.epub', None, username='ro', status=FORBIDDEN) content = b'content' filename = 'test add - XXX.txt' - data = r(filename, content) + data = a(filename, content) s = BytesIO(content) s.name = filename mi = get_metadata(s, stream_type='txt') @@ -182,5 +190,6 @@ class ContentTest(LibraryBaseTest): r, q = make_request(conn, '/get/txt/{}'.format(data['book_id']), username='12', password='test', prefix='') ae(r.status, OK) ae(q, content) - + d((1,), username='ro', status=FORBIDDEN) + d((1, data['book_id'])) # }}}