def add_portable(db, portable_url): ''' Registers and import portable library :param db: database connection :param portable_url: url of the portable library ''' LOG.info('>>> Registering portable {}'.format(portable_url)) try: headers = {"Accept-Encoding": "gzip"} libjs = requests.get(portable_url + '/static/data.js', headers=headers, stream=True).text.strip() # remove javascript wrapper around json libjson = libjs[libjs.find('{'):-1] catalog = simplejson.loads(libjson) res, err = import_catalog(db, catalog, portable_url) if err: return err return res except requests.ConnectionError: return utils.ser2json( 'Error while registering portable: connection error') except Exception: LOG.error('Registering portable', exc_info=True) return utils.ser2json('Error while registering portable. Check logs...')
def remove_portable(db, url): ''' Removes registered portable library with given lib_uuid ''' q = {'portable_url': url} portable_cat = db.catalog.find_one(q) if portable_cat: db.books.remove({'library_uuid': portable_cat['library_uuid']}) db.catalog.remove({'library_uuid': portable_cat['library_uuid']}) return utils.ser2json('Library removed.') else: return utils.ser2json('Portable not found or doomed.')
def remove_portable(db, url): ''' Removes registered portable library with given lib_uuid ''' q = {'portable': True, 'portable_url': url} portable_cat = db.catalog.find_one(q) if portable_cat: remove_from_library(db, portable_cat['library_uuid'], portable_cat['books']) db.catalog.remove(q) return utils.ser2json('Library removed.') return utils.ser2json('Error while removing portable...')
def remove_portable(db, url): ''' Removes registered portable library with given lib_uuid ''' q = {'portable': True, 'portable_url': url} portable_cat = db.catalog.find_one(q) if portable_cat: remove_from_library( db, portable_cat['library_uuid'], portable_cat['books']) db.catalog.remove(q) return utils.ser2json('Library removed.') else: return utils.ser2json('Portable not found') return utils.ser2json('Error while removing portable...')
def add_portable(db, url): print('Registering portable: with url {}'.format(url)) try: libjs = requests.get(url + '/static/data.js').text libjson = libjs[libjs.find('{'):-1] catalog = simplejson.loads(libjson) res = import_catalog(db, catalog, url) return res except ValueError as e: return utils.ser2json('Already registered...') except requests.ConnectionError as e: print('Registering portable: ConnectionError {}'.format(e)) except Exception as e: print('Registering portable: Exception {}'.format(e)) return utils.ser2json('Error while registering portable...')
def get_books(db, page, query={}): ''' Reads and returns books from the database. page: parameter for _paginate_ function ''' # query q = {} # extract search parameters and build query for k, v in query.iteritems(): if v: words = v.encode('utf-8').split(' ') match_pattern = {'$regex': '.*'.join(words), '$options': 'i'} if k in ['authors', 'title', 'librarian']: q[k] = match_pattern # search all metadata else: q = { "$or": [{ "title": match_pattern }, { "authors": match_pattern }, { "comments": match_pattern }, { "tags": match_pattern }, { "publisher": match_pattern }, { "identifiers": match_pattern }] } # get all libraries that have active ssh tunnel or reference portables active_catalogs = db.catalog.find({ '$or': [{ 'tunnel': { '$in': get_active_tunnels()[0] } }, { 'portable': True }] }) q['library_uuid'] = {'$in': [i['library_uuid'] for i in active_catalogs]} librarians = active_catalogs.distinct('librarian') authors = db.books.find(q, PUBLIC_BOOK_FIELDS).distinct('authors') titles = db.books.find(q, PUBLIC_BOOK_FIELDS).distinct('title') # paginate books items, next_page, on_page, total = paginate( db.books.find(q, PUBLIC_BOOK_FIELDS).sort('title_sort'), page) # return serialized books with availability of next page return utils.ser2json({ 'books': list(items), 'next_page': next_page, 'on_page': on_page, 'total': total, 'librarians': librarians, 'authors': authors, 'titles': titles })
def get_portables(db): ''' Returns all registered portable libraries ''' return utils.ser2json(list(db.catalog.find( {'portable': True}, {'librarian': 1, 'library_uuid': 1, '_id': 0})))
def get_active_librarians(db): time.sleep(0.5) active_catalogs = db.catalog.find( {'$or': [ {'tunnel': {'$in': [p for p in get_active_ports()]}}, {'portable': True}]}) librarians = active_catalogs.distinct('librarian') #print([c['librarian'] for c in active_catalogs], librarians) return utils.ser2json({'librarians': librarians})
def get_catalog(db, uuid): ''' Read catalog entry from the database and return json representation ''' return utils.ser2json(db.catalog.find_one( {'library_uuid': uuid}, {'books': 1, 'last_modified': 1, '_id': 0}))
def get_catalogs(db): ''' for testing purposes ''' return utils.ser2json(db.catalog.find( {}, {'library_uuid': 1, 'librarian': 1, '_id': 0}))
def get_catalogs(db): ''' for testing purposes ''' return utils.ser2json( db.catalog.find({}, { 'library_uuid': 1, 'librarian': 1, '_id': 0 }))
def get_catalog(db, uuid): ''' Read catalog entry from the database and return json representation ''' return utils.ser2json( db.catalog.find_one({'library_uuid': uuid}, { 'books': 1, 'last_modified': 1, '_id': 0 }))
def get_portables(db): ''' Returns all registered portable libraries ''' return utils.ser2json( list( db.catalog.find({'portable': True}, { 'librarian': 1, 'library_uuid': 1, '_id': 0 })))
def get_active_librarians(db): time.sleep(0.5) active_catalogs = db.catalog.find({ '$or': [{ 'tunnel': { '$in': [p for p in get_active_ports()] } }, { 'portable': True }] }) librarians = active_catalogs.distinct('librarian') #print([c['librarian'] for c in active_catalogs], librarians) return utils.ser2json({'librarians': librarians})
def get_book(db, uuid): ''' Returns book with the param uuid ''' book = db.books.find_one({'uuid': uuid}, PUBLIC_SINGLE_BOOK_FIELDS) return utils.ser2json(book)
def book(self, uuid): ''' Single book page ''' book = libraries.get_book(cherrypy.db, uuid=uuid) return utils.ser2json(book)
def get_autocomplete(db): ''' Returns pre-computed autocomplete data ''' return utils.ser2json(db.autocomplete.find_one({}, {'_id': 0}))
def get_books(db, last_id, query={}): ''' Reads and returns books from the database. ''' # query q = {} LOG.debug('>' * 30) LOG.debug('>>> QUERY: {}, LAST_ID: {}'.format(query, last_id)) # extract search parameters and build query # text + property q_text = query.get('text') q_property = query.get('property', 'all') if q_text: q_words = q_text.encode('utf-8').split(' ') match_pattern = {'$regex': '.*'.join(q_words), '$options': 'i'} if q_property in ['authors', 'title', 'tags']: q[q_property] = match_pattern elif q_property == 'pubdate': # validate entered date, but query as string try: date = datetime.strptime(q_text, '%Y-%m-%d') q[q_property] = { '$regex': '^{}.*'.format(q_text), '$options': 'i' } except Exception as e: LOG.error('invalid date: {}'.format(q_text)) elif q_property == 'formats': q[q_property] = {'$all': [i.upper() for i in q_words]} else: q = { "$or": [{ 'title': match_pattern }, { 'authors': match_pattern }, { 'comments': match_pattern }, { 'tags': match_pattern }, { 'publisher': match_pattern }, { 'identifiers': match_pattern }] } # dropdown value + property q_dproperty = query.get('dproperty') q_dvalue = query.get('dvalue') if q_dvalue: if q_dproperty == 'librarians': q['librarian'] = q_dvalue.encode('utf-8') elif q_dproperty == 'collections': q['collection'] = q_dvalue.encode('utf-8') else: LOG.error('unsupported dropdown property: {}'.format(q_dproperty)) # get all libraries that have active ssh tunnel or reference portables active_tunnels = get_active_tunnels() LOG.debug('>>> Active_tunnels: {}'.format(active_tunnels)) active_catalogs = db.catalog.find( {'$or': [{ 'tunnel': { '$in': active_tunnels } }, { 'portable': True }]}) q['library_uuid'] = {'$in': [i['library_uuid'] for i in active_catalogs]} # infinite scroll query part if last_id: q['_id'] = {'$lt': ObjectId(last_id)} # fetch final cursor LOG.debug('>>> FINAL QUERY: {}'.format(q)) dbb = db.books.find(q, PUBLIC_BOOK_FIELDS).sort('last_modified', -1) # do infinite loading books = list(dbb.limit(settings.ITEMS_PER_PAGE)) # calculate last_id current_last_id = None if books and len(books) == settings.ITEMS_PER_PAGE: current_last_id = str(books[len(books) - 1]['_id']) return utils.ser2json({ 'books': books, 'last_id': current_last_id, })
def get_books(db, last_id, query={}): ''' Reads and returns books from the database. ''' # query q = {} LOG.debug('>'*30) LOG.debug('>>> QUERY: {}, LAST_ID: {}'.format(query, last_id)) # extract search parameters and build query # text + property q_text = query.get('text') q_property = query.get('property', 'all') if q_text: q_words = q_text.encode('utf-8').split(' ') match_pattern = {'$regex': '.*'.join(q_words), '$options': 'i'} if q_property in ['authors', 'title', 'tags']: q[q_property] = match_pattern elif q_property == 'pubdate': # validate entered date, but query as string try: _date = datetime.strptime(q_text, '%Y-%m-%d') q[q_property] = {'$regex': '^{}.*'.format(q_text), '$options': 'i'} except Exception as e: LOG.error('invalid date: {}'.format(q_text)) elif q_property == 'formats': q[q_property] = {'$all': [i.upper() for i in q_words]} else: q = {"$or": [{'title': match_pattern}, {'authors': match_pattern}, {'comments': match_pattern}, {'tags': match_pattern}, {'publisher': match_pattern}, {'identifiers': match_pattern}]} # dropdown value + property q_dproperty = query.get('dproperty') q_dvalue = query.get('dvalue') if q_dvalue: if q_dproperty == 'librarians': q['librarian'] = q_dvalue.encode('utf-8') elif q_dproperty == 'collections': q['collection'] = q_dvalue.encode('utf-8') else: LOG.error('unsupported dropdown property: {}'.format(q_dproperty)) # get all libraries that have active ssh tunnel or reference portables active_tunnels = get_active_tunnels() LOG.debug('>>> Active_tunnels: {}'.format(active_tunnels)) active_catalogs = db.catalog.find( {'$or': [ {'tunnel': {'$in': active_tunnels}}, {'portable': True}]}) q['library_uuid'] = {'$in': [i['library_uuid'] for i in active_catalogs]} # infinite scroll query part if last_id: q['_id'] = {'$lt': ObjectId(last_id)} # fetch final cursor LOG.debug('>>> FINAL QUERY: {}'.format(q)) dbb = db.books.find(q, PUBLIC_BOOK_FIELDS).sort('_id', -1) # do infinite loading books = list(dbb.limit(settings.ITEMS_PER_PAGE)) # calculate last_id current_last_id = None if books and len(books) == settings.ITEMS_PER_PAGE: current_last_id = str(books[len(books) - 1]['_id']) return utils.ser2json({ 'books': books, 'last_id': current_last_id, })
def get_catalogs(db): ''' for testing purposes ''' return utils.ser2json(db.catalog.count())