Example #1
0
    def test_library_restrictions(self):  # {{{
        from calibre.srv.opts import Options
        from calibre.srv.handler import Handler
        from calibre.db.legacy import create_backend
        opts = Options(userdb=':memory:')
        Data = namedtuple('Data', 'username')
        with TemporaryDirectory() as base:
            l1, l2, l3 = map(lambda x: os.path.join(base, 'l' + x), '123')
            for l in (l1, l2, l3):
                create_backend(l).close()
            ctx = Handler((l1, l2, l3), opts).router.ctx
            um = ctx.user_manager

            def get_library(username=None, library_id=None):
                ans = ctx.get_library(Data(username), library_id=library_id)
                return os.path.basename(ans.backend.library_path)

            def library_info(username=None):
                lmap, defaultlib = ctx.library_info(Data(username))
                lmap = {k:os.path.basename(v) for k, v in lmap.iteritems()}
                return lmap, defaultlib

            self.assertEqual(get_library(), 'l1')
            self.assertEqual(library_info()[0], {'l%d'%i:'l%d'%i for i in range(1, 4)})
            self.assertEqual(library_info()[1], 'l1')
            self.assertRaises(HTTPForbidden, get_library, 'xxx')
            um.add_user('a', 'a')
            self.assertEqual(library_info('a')[0], {'l%d'%i:'l%d'%i for i in range(1, 4)})
            um.update_user_restrictions('a', {'blocked_library_names': ['L2']})
            self.assertEqual(library_info('a')[0], {'l%d'%i:'l%d'%i for i in range(1, 4) if i != 2})
            um.update_user_restrictions('a', {'allowed_library_names': ['l3']})
            self.assertEqual(library_info('a')[0], {'l%d'%i:'l%d'%i for i in range(1, 4) if i == 3})
            self.assertEqual(library_info('a')[1], 'l3')
            self.assertRaises(HTTPForbidden, get_library, 'a', 'l1')
            self.assertRaises(HTTPForbidden, get_library, 'xxx')
Example #2
0
    def test_library_restrictions(self):  # {{{
        from calibre.srv.opts import Options
        from calibre.srv.handler import Handler
        from calibre.db.legacy import create_backend
        opts = Options(userdb=':memory:')
        Data = namedtuple('Data', 'username')
        with TemporaryDirectory() as base:
            l1, l2, l3 = map(lambda x: os.path.join(base, 'l' + x), '123')
            for l in (l1, l2, l3):
                create_backend(l).close()
            ctx = Handler((l1, l2, l3), opts).router.ctx
            um = ctx.user_manager

            def get_library(username=None, library_id=None):
                ans = ctx.get_library(Data(username), library_id=library_id)
                return os.path.basename(ans.backend.library_path)

            def library_info(username=None):
                lmap, defaultlib = ctx.library_info(Data(username))
                lmap = {k:os.path.basename(v) for k, v in iteritems(lmap)}
                return lmap, defaultlib

            self.assertEqual(get_library(), 'l1')
            self.assertEqual(library_info()[0], {'l%d'%i:'l%d'%i for i in range(1, 4)})
            self.assertEqual(library_info()[1], 'l1')
            self.assertRaises(HTTPForbidden, get_library, 'xxx')
            um.add_user('a', 'a')
            self.assertEqual(library_info('a')[0], {'l%d'%i:'l%d'%i for i in range(1, 4)})
            um.update_user_restrictions('a', {'blocked_library_names': ['L2']})
            self.assertEqual(library_info('a')[0], {'l%d'%i:'l%d'%i for i in range(1, 4) if i != 2})
            um.update_user_restrictions('a', {'allowed_library_names': ['l3']})
            self.assertEqual(library_info('a')[0], {'l%d'%i:'l%d'%i for i in range(1, 4) if i == 3})
            self.assertEqual(library_info('a')[1], 'l3')
            self.assertRaises(HTTPForbidden, get_library, 'a', 'l1')
            self.assertRaises(HTTPForbidden, get_library, 'xxx')
Example #3
0
    def copy_to_library(self, loc, delete_after=False):
        rows = self.gui.library_view.selectionModel().selectedRows()
        if not rows or len(rows) == 0:
            return error_dialog(self.gui, _('Cannot copy'),
                    _('No books selected'), show=True)
        ids = list(map(self.gui.library_view.model().id, rows))
        db = self.gui.library_view.model().db
        if not db.exists_at(loc):
            return error_dialog(self.gui, _('No library'),
                    _('No library found at %s')%loc, show=True)

        # Open the new db so we can check the custom columns. We use only the
        # backend since we only need the custom column definitions, not the
        # rest of the data in the db. We also do not want the user defined
        # formatter functions because loading them can poison the template cache
        global libraries_with_checked_columns

        from calibre.db.legacy import create_backend
        newdb = create_backend(loc, load_user_formatter_functions=False)

        continue_processing = True
        with closing(newdb):
            if newdb.library_id not in libraries_with_checked_columns[db.library_id]:

                newdb_meta = newdb.field_metadata.custom_field_metadata()
                incompatible_columns = []
                missing_columns = []
                for k, m in db.field_metadata.custom_iteritems():
                    if k not in newdb_meta:
                        missing_columns.append(k)
                    elif not self._column_is_compatible(m, newdb_meta[k]):
                        # Note that composite columns are always assumed to be
                        # compatible. No attempt is made to copy the template
                        # from the source to the destination.
                        incompatible_columns.append(k)

                if missing_columns or incompatible_columns:
                    continue_processing = ask_about_cc_mismatch(self.gui, db, newdb,
                                            missing_columns, incompatible_columns)
                if continue_processing:
                    libraries_with_checked_columns[db.library_id].add(newdb.library_id)

        newdb.close()
        del newdb
        if not continue_processing:
            return
        duplicate_ids = self.do_copy(ids, db, loc, delete_after, False)
        if duplicate_ids:
            d = DuplicatesQuestion(self.gui, duplicate_ids, loc)
            if d.exec_() == d.Accepted:
                ids = d.ids
                if ids:
                    self.do_copy(list(ids), db, loc, delete_after, add_duplicates=True)
Example #4
0
 def create_db(self, library_path):
     from calibre.db.legacy import create_backend
     from calibre.db.cache import Cache
     d = os.path.dirname
     src = os.path.join(d(d(d(os.path.abspath(__file__)))), 'db', 'tests', 'metadata.db')
     dest = os.path.join(library_path, 'metadata.db')
     shutil.copy2(src, dest)
     db = Cache(create_backend(library_path))
     db.init()
     db.set_cover({1:I('lt.png', data=True), 2:I('polish.png', data=True)})
     db.add_format(1, 'FMT1', BytesIO(b'book1fmt1'), run_hooks=False)
     db.add_format(1, 'EPUB', open(P('quick_start/eng.epub'), 'rb'), run_hooks=False)
     db.add_format(1, 'FMT2', BytesIO(b'book1fmt2'), run_hooks=False)
     db.add_format(2, 'FMT1', BytesIO(b'book2fmt1'), run_hooks=False)
     db.backend.conn.close()
     return dest
Example #5
0
 def create_db(self, library_path):
     from calibre.db.legacy import create_backend
     from calibre.db.cache import Cache
     d = os.path.dirname
     src = os.path.join(d(d(d(os.path.abspath(__file__)))), 'db', 'tests', 'metadata.db')
     dest = os.path.join(library_path, 'metadata.db')
     shutil.copy2(src, dest)
     db = Cache(create_backend(library_path))
     db.init()
     db.set_cover({1:I('lt.png', data=True), 2:I('polish.png', data=True)})
     db.add_format(1, 'FMT1', BytesIO(b'book1fmt1'), run_hooks=False)
     db.add_format(1, 'EPUB', open(P('quick_start/eng.epub'), 'rb'), run_hooks=False)
     db.add_format(1, 'FMT2', BytesIO(b'book1fmt2'), run_hooks=False)
     db.add_format(2, 'FMT1', BytesIO(b'book2fmt1'), run_hooks=False)
     db.backend.conn.close()
     return dest
Example #6
0
def init_library(library_path):
    db = Cache(create_backend(library_path))
    db.init()
    return db
Example #7
0
    def copy_to_library(self, loc, delete_after=False):
        rows = self.gui.library_view.selectionModel().selectedRows()
        if not rows or len(rows) == 0:
            return error_dialog(self.gui, _('Cannot copy'),
                    _('No books selected'), show=True)
        ids = list(map(self.gui.library_view.model().id, rows))
        db = self.gui.library_view.model().db
        if not db.exists_at(loc):
            return error_dialog(self.gui, _('No library'),
                    _('No library found at %s')%loc, show=True)

        aname = _('Moving to') if delete_after else _('Copying to')
        dtitle = '%s %s'%(aname, os.path.basename(loc))

        self.pd = ProgressDialog(dtitle, min=0, max=len(ids)-1,
                parent=self.gui, cancelable=False)

        def progress(idx, title):
            self.pd.set_msg(title)
            self.pd.set_value(idx)

        # Open the new db so we can check the custom columns. We use only the
        # backend since we only need the custom column definitions, not the
        # rest of the data in the db.

        global libraries_with_checked_columns

        from calibre.db.legacy import create_backend
        newdb = create_backend(loc)

        continue_processing = True
        with closing(newdb):
            if newdb.library_id not in libraries_with_checked_columns[db.library_id]:

                newdb_meta = newdb.field_metadata.custom_field_metadata()
                incompatible_columns = []
                missing_columns = []
                for k, m in db.field_metadata.custom_iteritems():
                    if m['datatype'] == 'composite':
                        continue
                    if k not in newdb_meta:
                        missing_columns.append(k)
                    elif not self._column_is_compatible(m, newdb_meta[k]):
                        incompatible_columns.append(k)

                if missing_columns or incompatible_columns:
                    continue_processing = ask_about_cc_mismatch(self.gui, db, newdb,
                                            missing_columns, incompatible_columns)
                if continue_processing:
                    libraries_with_checked_columns[db.library_id].add(newdb.library_id)

        newdb.close()
        del newdb
        if not continue_processing:
            return

        self.worker = Worker(ids, db, loc, Dispatcher(progress),
                             Dispatcher(self.pd.accept), delete_after)
        self.worker.start()

        self.pd.exec_()

        donemsg = _('Copied %(num)d books to %(loc)s')
        if delete_after:
            donemsg = _('Moved %(num)d books to %(loc)s')

        if self.worker.error is not None:
            e, tb = self.worker.error
            error_dialog(self.gui, _('Failed'), _('Could not copy books: ') + e,
                    det_msg=tb, show=True)
        else:
            self.gui.status_bar.show_message(donemsg %
                    dict(num=len(ids), loc=loc), 2000)
            if self.worker.auto_merged_ids:
                books = '\n'.join(self.worker.auto_merged_ids.itervalues())
                info_dialog(self.gui, _('Auto merged'),
                        _('Some books were automatically merged into existing '
                            'records in the target library. Click Show '
                            'details to see which ones. This behavior is '
                            'controlled by the Auto merge option in '
                            'Preferences->Adding books.'), det_msg=books,
                        show=True)
            if delete_after and self.worker.processed:
                v = self.gui.library_view
                ci = v.currentIndex()
                row = None
                if ci.isValid():
                    row = ci.row()

                v.model().delete_books_by_id(self.worker.processed,
                        permanent=True)
                self.gui.iactions['Remove Books'].library_ids_deleted(
                        self.worker.processed, row)
Example #8
0
def init_library(library_path, is_default_library):
    db = Cache(
        create_backend(library_path,
                       load_user_formatter_functions=is_default_library))
    db.init()
    return db
Example #9
0
def init_library(library_path):
    db = Cache(create_backend(library_path))
    db.init()
    return db
Example #10
0
def init_library(library_path, is_default_library):
    db = Cache(
        create_backend(
            library_path, load_user_formatter_functions=is_default_library))
    db.init()
    return db