def teardown(self): # Close the session. self._db.close() # Roll back all database changes that happened during this # test, whether in the session that was just closed or some # other session. self.transaction.rollback() # Remove any database objects cached in the model classes but # associated with the now-rolled-back session. Collection.reset_cache() ConfigurationSetting.reset_cache() DataSource.reset_cache() DeliveryMechanism.reset_cache() ExternalIntegration.reset_cache() Genre.reset_cache() Library.reset_cache() # Also roll back any record of those changes in the # Configuration instance. for key in [ Configuration.SITE_CONFIGURATION_LAST_UPDATE, Configuration.LAST_CHECKED_FOR_SITE_CONFIGURATION_UPDATE ]: if key in Configuration.instance: del(Configuration.instance[key]) if self.search_mock: self.search_mock.stop()
def teardown(self): # Close the session. self._db.close() # Roll back all database changes that happened during this # test, whether in the session that was just closed or some # other session. self.transaction.rollback() # Remove any database objects cached in the model classes but # associated with the now-rolled-back session. Collection.reset_cache() ConfigurationSetting.reset_cache() DataSource.reset_cache() DeliveryMechanism.reset_cache() ExternalIntegration.reset_cache() Genre.reset_cache() Library.reset_cache() # Also roll back any record of those changes in the # Configuration instance. for key in [ Configuration.SITE_CONFIGURATION_LAST_UPDATE, Configuration.LAST_CHECKED_FOR_SITE_CONFIGURATION_UPDATE ]: if key in Configuration.instance: del (Configuration.instance[key]) if self.search_mock: self.search_mock.stop()
class test_Library(unittest.TestCase): def setUp(self): self.d = Library(1, 'CRUX', 'Jacob', 'Student', 'William', 'Bob', '2077-02-22', 'Croatia') def test_get_ID(self): self.assertEqual(1, self.d.get_BookID()) def test_get_BookTitle(self): self.assertEqual('CRUX', self.d.get_BookTitle())
def delete(self): lbr_obj = Library(self.txtBookID.get(), self.cboBookTitle.get(), self.txtAuthor.get(), self.cboMemberType.get(), self.txtFirstName.get(), self.txtSurname.get(), self.txtDateBorrowed.get(), self.txtAddress.get()) query = ('delete from management where BookID=%s') values = (lbr_obj.get_BookID(),) self.dbconnect.delete(query, values) messagebox.showinfo('Success', 'Data deleted successfully') self.fetch_data() self.clear()
def add(self): lbr_obj = Library(self.txtBookID.get(), self.cboBookTitle.get(), self.txtAuthor.get(), self.cboMemberType.get(), self.txtFirstName.get(), self.txtSurname.get(), self.txtDateBorrowed.get(), self.txtAddress.get()) query = 'insert into management values(%s,%s,%s,%s,%s,%s,%s,%s);' values = (lbr_obj.get_BookID(), lbr_obj.get_BookTitle(), lbr_obj.get_Author(), lbr_obj.get_MemberType(), lbr_obj.get_FirstName(), lbr_obj.get_Surname(), lbr_obj.get_DateBorrowed(), lbr_obj.get_Address()) self.dbconnect.insert(query, values) messagebox.showinfo('Success', 'Data inserted successfully') self.fetch_data() self.clear()
def search(self, location, live=True): query = flask.request.args.get('q') if live: search_controller = 'search' else: search_controller = 'search_qa' if query: # Run the query and send the results. results = Library.search(self._db, location, query, production=live) this_url = self.app.url_for(search_controller, q=query) catalog = OPDSCatalog(self._db, unicode(_('Search results for "%s"')) % query, this_url, results, annotator=self.annotator, live=live) return catalog_response(catalog) else: # Send the search form. body = self.OPENSEARCH_TEMPLATE % dict( name=_("Find your library"), description=_("Search by ZIP code, city or library name."), tags="", url_template=self.app.url_for(search_controller) + "?q={searchTerms}") headers = {} headers['Content-Type'] = OPENSEARCH_MEDIA_TYPE headers['Cache-Control'] = "public, no-transform, max-age: %d" % ( 3600 * 24 * 30) return Response(body, 200, headers)
def __init__(self, _db, collection=None, *args, **kwargs): self.access_token_requests = [] self.requests = [] self.responses = [] if not collection: # OverdriveAPI needs a Collection, but none was provided. # Just create a basic one. library = Library.instance(_db) collection, ignore = get_one_or_create( _db, Collection, name="Test Overdrive Collection", protocol=Collection.OVERDRIVE, create_method_kwargs=dict(external_account_id=u'c')) collection.external_integration.username = u'a' collection.external_integration.password = u'b' collection.external_integration.set_setting('website_id', 'd') library.collections.append(collection) # The constructor will always make a request for the collection token. self.queue_response( 200, content=self.mock_collection_token("collection token")) self.access_token_response = self.mock_access_token_response( "bearer token") super(MockOverdriveAPI, self).__init__(_db, collection, *args, **kwargs)
def update(self): lbr_obj= Library(self.txtBookID.get(),self.cboBookTitle.get(),self.txtAuthor.get(), self.cboMemberType.get(),self.txtFirstName.get(),self.txtSurname.get(), self.txtDateBorrowed.get(),self.txtAddress.get()) query='update management set BookTitle=%s,Author=%s,MemberType=%s,' \ 'FirstName=%s, Surname=%s, DateBorrowed=%s, Address=%s where BookID=%s;' values=(lbr_obj.get_BookTitle(), lbr_obj.get_Author(), lbr_obj.get_MemberType(), lbr_obj.get_FirstName(), lbr_obj.get_Surname(),lbr_obj.get_DateBorrowed(), lbr_obj.get_Address(),lbr_obj.get_BookID()) self.dbconnect.update(query, values) messagebox.showinfo('Success','Data updated successfully') self.fetch_data() self.clear()
def _account_library(self, snapshot_id, inode, name, pss): """There are likely to be lots of duplicated library names across a normal system, so cache libraries to avoid looking them up in the db repeatedly.""" # inode 0 is for memory fragments that aren't real files, # eg. [heap], [vdso], etc. if inode == 0: return # When using sandboxing, bind-mounting or symlinks, libraries may # show up in smaps with different paths. If the inode is the same # - on the same snapshot - then we can be sure the library is # actually the same one. The libraries are added to their own table # so statistics can be aggregated for them. basename = os.path.basename(name) if inode in self.known_libs: library = self.known_libs[inode] else: library = Library(basename, inode, snapshot_id) self.known_libs[inode] = library library.pss += pss library.shared_count += 1 library.num_fragments += 1
def validate_email(self): # Manually validate an email address, without the admin having to click on a confirmation link uuid = flask.request.form.get("uuid") email = flask.request.form.get("email") library = self.library_for_request(uuid) if isinstance(library, ProblemDetail): return library email_types = { "contact_email": Hyperlink.INTEGRATION_CONTACT_REL, "help_email": Hyperlink.HELP_REL, "copyright_email": Hyperlink.COPYRIGHT_DESIGNATED_AGENT_REL } hyperlink = None if email_types.get(email): hyperlink = Library.get_hyperlink(library, email_types[email]) if not hyperlink or not hyperlink.resource or isinstance( hyperlink, ProblemDetail): return INVALID_CONTACT_URI.detailed( "The contact URI for this library is missing or invalid") validation, is_new = get_one_or_create(self._db, Validation, resource=hyperlink.resource) validation.restart() validation.mark_as_successful() return self.library_details(uuid)
def all_libraries(self): """Find an iterator over all libraries, whatever 'all libraries' means in the context of this script. By default, 'all libraries' means all libraries in the production or testing stages. """ return self._db.query(Library).filter( Library._feed_restriction(production=False) )
def library_for_request(self, uuid): """Look up the library the user is trying to access.""" if not uuid: return LIBRARY_NOT_FOUND if not uuid.startswith("urn:uuid:"): uuid = "urn:uuid:" + uuid library = Library.for_urn(self._db, uuid) if not library: return LIBRARY_NOT_FOUND flask.request.library = library return library
def search_details(self): name = flask.request.form.get("name") search_results = Library.search(self._db, {}, name, production=False) if search_results: info = [ self.library_details(lib.internal_urn.split("uuid:")[1], lib) for lib in search_results ] return dict(libraries=info) else: return LIBRARY_NOT_FOUND
def fetch_data(self): lbr_obj = Library(self.txtBookID.get(), self.cboBookTitle.get(), self.txtAuthor.get(), self.cboMemberType.get(), self.txtFirstName.get(), self.txtSurname.get(), self.txtDateBorrowed.get(), self.txtAddress.get()) query = 'select * from management' rows=self.dbconnect.select(query) if len(rows) != 0: self.Library_table.delete( *self.Library_table.get_children()) for row in rows: self.Library_table.insert('', END, values=row)
def library_details(self, uuid, library=None): # Return complete information about one specific library. if not library: library = self.library_for_request(uuid) if isinstance(library, ProblemDetail): return library hyperlink_types = [ Hyperlink.INTEGRATION_CONTACT_REL, Hyperlink.HELP_REL, Hyperlink.COPYRIGHT_DESIGNATED_AGENT_REL ] hyperlinks = [ Library.get_hyperlink(library, x) for x in hyperlink_types ] contact_email, help_email, copyright_email = [ self._get_email(x) for x in hyperlinks ] contact_email_validated_at, help_email_validated_at, copyright_email_validated_at = [ self._validated_at(x) for x in hyperlinks ] contact_email_hyperlink, help_email_hyperlink, copyright_email_hyperlink = hyperlinks basic_info = dict(name=library.name, short_name=library.short_name, description=library.description, timestamp=library.timestamp, internal_urn=library.internal_urn, online_registration=str(library.online_registration), pls_id=library.pls_id.value, number_of_patrons=str(library.number_of_patrons)) urls_and_contact = dict( contact_email=contact_email, contact_validated=contact_email_validated_at, help_email=help_email, help_validated=help_email_validated_at, copyright_email=copyright_email, copyright_validated=copyright_email_validated_at, authentication_url=library.authentication_url, opds_url=library.opds_url, web_url=library.web_url, ) areas = self._areas(library.service_areas) stages = dict( library_stage=library._library_stage, registry_stage=library.registry_stage, ) return dict(uuid=uuid, basic_info=basic_info, urls_and_contact=urls_and_contact, areas=areas, stages=stages)
def nearby(self, location, live=True): qu = Library.nearby(self._db, location, production=live) qu = qu.limit(5) if live: nearby_controller = 'nearby' else: nearby_controller = 'nearby_qa' this_url = self.app.url_for(nearby_controller) catalog = OPDSCatalog(self._db, unicode(_("Libraries near you")), this_url, qu, annotator=self.annotator, live=live) return catalog_response(catalog)
def read_file(file_path): with open(file_path) as file: n_books, n_libraries, days = readline(file) scores = readline(file) book_scores = {i: score for i, score in enumerate(scores)} libraries = [] for i in range(n_libraries): _, signup_day, bpd = readline(file) books = {book: book_scores[book] for book in readline(file)} libraries.append(Library(books, signup_day, bpd)) return { 'book_scores': book_scores, 'days': days, 'libraries': libraries }
def __init__(self, _db, *args, **kwargs): self.responses = [] self.requests = [] library = Library.instance(_db) collection, ignore = get_one_or_create(_db, Collection, name="Test Enki Collection", protocol=Collection.ENKI, create_method_kwargs=dict( external_account_id=u'c', )) collection.external_integration.username = u'a' collection.external_integration.password = u'b' collection.external_integration.url = "http://enki.test/" library.collections.append(collection) super(MockEnkiAPI, self).__init__(_db, collection, *args, **kwargs)
def show_data(self, ev): data_row = self.Library_table.focus() content = self.Library_table.item(data_row) row = content['values'] lbr_obj = Library(self.txtBookID.delete('0',END), self.cboBookTitle.get(), self.txtAuthor.delete('0',END), self.cboMemberType.get(), self.txtFirstName.delete('0',END), self.txtSurname.delete('0',END), self.txtDateBorrowed.delete('0',END), self.txtAddress.delete('0',END)) self.txtBookID.insert(END, row[0]) self.cboBookTitle.set(row[1]) self.txtAuthor.insert(END, row[2]) self.cboMemberType.set(row[3]) self.txtFirstName.insert(END, row[4]) self.txtSurname.insert(END, row[5]) self.txtDateBorrowed.insert(END, row[6]) self.txtAddress.insert(END, row[7])
def from_environment(cls, _db): """Load a ThreeMAPI instance for the 'default' Bibliotheca collection. """ library = Library.instance(_db) collections = [x for x in library.collections if x.protocol == Collection.BIBLIOTHECA] if len(collections) == 0: # There are no Bibliotheca collections configured. return None if len(collections) > 1: raise ValueError( "Multiple Bibliotheca collections found for one library. This is not yet supported." ) [collection] = collections return cls(_db, collection)
def from_environment(cls, _db): """Load an Axis360API instance for the 'default' Axis 360 collection. """ library = Library.instance(_db) collections = [x for x in library.collections if x.protocol == Collection.AXIS_360] if len(collections) == 0: # There are no Axis 360 collections configured. return None if len(collections) > 1: raise ValueError( "Multiple Axis 360 collections found for one library. This is not yet supported." ) [collection] = collections return cls(_db, collection)
def __init__(self, _db, with_token=True, *args, **kwargs): library = Library.instance(_db) collection, ignore = get_one_or_create( _db, Collection, name="Test Axis 360 Collection", protocol=Collection.AXIS_360, create_method_kwargs=dict( external_account_id=u'c', ) ) collection.external_integration.username = u'a' collection.external_integration.password = u'b' collection.external_integration.url = u"http://axis.test/" library.collections.append(collection) super(MockAxis360API, self).__init__(_db, collection, *args, **kwargs) if with_token: self.token = "mock token" self.responses = [] self.requests = []
def __init__(self, _db, collection=None, base_path=None): if not collection: # OneClickAPI needs a Collection, but none was provided. # Just create a basic one. library = Library.instance(_db) collection, ignore = get_one_or_create( _db, Collection, name="Test OneClick Collection", protocol=Collection.ONE_CLICK, create_method_kwargs=dict( external_account_id=u'library_id_123', )) collection.external_integration.password = u'abcdef123hijklm' self.responses = [] self.requests = [] base_path = base_path or os.path.split(__file__)[0] self.resource_path = os.path.join(base_path, "files", "oneclick") return super(MockOneClickAPI, self).__init__(_db, collection)
def from_config(cls, _db): """Load a OneClickAPI instance for the 'default' OneClick collection. """ library = Library.instance(_db) collections = [ x for x in library.collections if x.protocol == Collection.ONE_CLICK ] if len(collections) == 0: # There are no OneClick collections configured. return None if len(collections) > 1: raise ValueError( "Multiple OneClick collections found for one library. This is not yet supported." ) [collection] = collections return cls(_db, collection)
def __init__(self): self.view = View() self.library = Library() self.player = Player(self.library)
class Controller: """handle menu transitions, and act as gobetween for model/view""" def __init__(self): self.view = View() self.library = Library() self.player = Player(self.library) def handle_track_select(self): display = self.view.menu_stack[-1] selected_item = display.get_selected_item() path = selected_item.path name = os.path.basename(display.menu_path) if path == cfg.media_option_items[MediaOptions.PLAY]: self.player.play(display.menu_path) self.view.menu_stack.pop() self.view.notify(cfg.playing_str) elif path == cfg.media_option_items[MediaOptions.QUEUE_NEXT]: self.player.queue_next(display.menu_path) self.view.menu_stack.pop() self.view.notify(name + cfg.play_next_str) elif path == cfg.media_option_items[MediaOptions.QUEUE_LAST]: self.player.queue_last(display.menu_path) self.view.menu_stack.pop() self.view.notify(name + cfg.play_last_str) def handle_media_select(self, item_path: str, display: Display): items = [] for opt in cfg.media_option_items: items.append(DisplayItem(ItemType.Menu, opt)) new_display = Display(items, item_path) self.view.menu_stack.append(new_display) def handle_dir_select(self, item_path: str, display): item_name = item_path.split(os.sep)[-1] display_path = display.menu_path + os.sep + item_name item_list = self.library.get_disk_items(item_path) new_display = Display(item_list, display_path) self.view.menu_stack.append(new_display) def handle_queue_select(self): display_path = cfg.home_menu_items[HomeOptions.QUEUE] display_items = [] for item in self.player.next_tracks: display_items.append(DisplayItem(ItemType.Track, item)) new_display = Display(display_items, display_path) self.view.menu_stack.append(new_display) def handle_playlist_select(self, item, ext, display): tracks = self.library.get_playlist_tracks(display.menu_path) playlist = os.path.basename(display.menu_path) items = [] for track in tracks: items.append(DisplayItem(ItemType.Track, track)) if item.path == cfg.media_option_items[MediaOptions.VIEW]: new_display = Display(items, display.menu_path) self.view.menu_stack.append(new_display) elif item.path == cfg.media_option_items[MediaOptions.PLAY]: if not self.player.play(display.menu_path): self.view.notify(cfg.play_error_str) else: self.view.notify(cfg.playing_str) self.view.menu_stack.pop() elif item.path == cfg.media_option_items[MediaOptions.QUEUE_NEXT]: self.player.queue_next(tracks) self.view.menu_stack.pop() self.view.notify(playlist + cfg.play_next_str) elif item.path == cfg.media_option_items[MediaOptions.QUEUE_LAST]: self.player.queue_last(tracks) self.view.menu_stack.pop() self.view.notify(playlist + cfg.play_last_str) def handle_menu_select(self, item, ext, display): if ext in cfg.playlist_formats: self.handle_playlist_select(item, ext, display) if ext in cfg.music_formats: self.handle_track_select() def handle_lib_subset(self): curr_display = self.view.menu_stack[-1] menu_path = curr_display.menu_path key = curr_display.get_selected_item().path if cfg.home_menu_items[HomeOptions.ALBUMS] in menu_path: key_items = self.library.albums.get(key) elif cfg.home_menu_items[HomeOptions.ARTISTS] in menu_path: key_items = self.library.artists.get(key) elif cfg.home_menu_items[HomeOptions.GENRES] in menu_path: key_items = self.library.genres.get(key) if not key_items: self.view.notify(cfg.load_error_str) return else: new_item_list = [] for item in key_items: new_item_list.append(DisplayItem(ItemType.Track, item)) new_path = os.path.join(curr_display.menu_path, key) new_display = Display(new_item_list, new_path) self.view.menu_stack.append(new_display) def handle_album_select(self): path = cfg.home_menu_items[HomeOptions.ALBUMS] display_items = [] for key in self.library.albums.keys(): display_items.append(DisplayItem(ItemType.Directory, key)) display = Display(display_items, path) self.view.menu_stack.append(display) def handle_artist_select(self): path = cfg.home_menu_items[HomeOptions.ARTISTS] display_items = [] for key in self.library.artists.keys(): display_items.append(DisplayItem(ItemType.Directory, key)) display = Display(display_items, path) self.view.menu_stack.append(display) def handle_genre_select(self): path = cfg.home_menu_items[HomeOptions.GENRES] display_items = [] for key in self.library.genres: display_items.append(DisplayItem(ItemType.Directory, key)) display = Display(display_items, path) self.view.menu_stack.append(display) def handle_home_select(self): display = self.view.menu_stack[-1] index = display.index + display.start_index if index == HomeOptions.EXIT: return False elif index == HomeOptions.PLAYLISTS: path = cfg.home_menu_items[HomeOptions.PLAYLISTS] items = self.library.get_disk_items(cfg.playlist_dir) display = Display(items, path) self.view.menu_stack.append(display) elif index == HomeOptions.TRACKS: path = cfg.home_menu_items[HomeOptions.TRACKS] display = Display(self.library.get_tracks(), path) self.view.menu_stack.append(display) elif index == HomeOptions.ALBUMS: self.handle_album_select() elif index == HomeOptions.ARTISTS: self.handle_artist_select() elif index == HomeOptions.GENRES: self.handle_genre_select() elif index == HomeOptions.QUEUE: self.handle_queue_select() elif index == HomeOptions.SETTINGS: self.view.notify(cfg.not_implemented_str) return True def handle_select(self): display: Display = self.view.menu_stack[-1] item: DisplayItem = display.get_selected_item() if item is None: return ext: str = os.path.splitext(display.menu_path)[1] lib_subsets = [ cfg.home_menu_items[i] for i in (HomeOptions.ALBUMS, HomeOptions.GENRES) ] if not display.menu_path: return self.handle_home_select() elif display.menu_path in lib_subsets: self.handle_lib_subset() elif item.item_type is ItemType.Menu: self.handle_menu_select(item, ext, display) elif item.item_type is ItemType.Directory: self.handle_dir_select(item.path, display) elif item.item_type in (ItemType.Track, ItemType.Playlist): self.handle_media_select(item.path, display) def on_press(self, key: KeyCode): """Callback for handling user input.""" if hasattr(key, 'char'): if key.char == 'p': self.player.play() elif key.char == 'a': self.player.pause() elif key.char == 'n': self.player.skip_forward() elif key.char == 'l': self.player.skip_back() self.view.notify(self.player.get_state_str()) else: if key == Key.left: self.view.navigate_back() # can't navigate forward or select on an empty menu elif self.view.menu_stack[-1].items is None: return elif key == Key.up: self.view.navigate_up() elif key == Key.down: self.view.navigate_down() elif key == Key.right: return self.handle_select() def tick(self): """periodic ui update""" metadata = self.player.get_metadata() display = self.view.menu_stack[-1] if display.menu_path == cfg.home_menu_items[HomeOptions.QUEUE]: display_items = [] for item in self.player.next_tracks: display_items.append(DisplayItem(ItemType.Track, item)) new_display = display._replace(items=display_items) self.view.menu_stack.pop() self.view.menu_stack.append(new_display) self.view.update_status(metadata) self.view.update_menu() self.view.screen.refresh() def run(self): """splits into two threads for ui and pynput""" listener = Listener(on_press=self.on_press) try: listener.start() while listener.running: self.tick() sleep(cfg.refresh_rate) finally: del self.view del self.player del self.library
def dupe_check(candidate): return Library.for_short_name(self._db, candidate) is not None
def run(self, cmd_args=None, stdout=sys.stdout): parsed = self.parse_command_line(self._db, cmd_args) for library in Library.search(self._db, None, parsed.query[0]): stdout.write("%s: %s" % (library.name, library.opds_url)) stdout.write("\n")
def __init__(self): self._broker = Broker() self._library = Library(self._broker) self._ids = Ids()
def setUp(self): self.d = Library(1, 'CRUX', 'Jacob', 'Student', 'William', 'Bob', '2077-02-22', 'Croatia')
def libraries_opds(self, live=True, location=None): """Return all the libraries in OPDS format :param live: If this is True, then only production libraries are shown. :param location: If this is set, then libraries near this point will be promoted out of the alphabetical list. """ alphabetical = self._db.query(Library).order_by(Library.name) # We always want to filter out cancelled libraries. If live, we also filter out # libraries that are in the testing stage, i.e. only show production libraries. alphabetical = alphabetical.filter( Library._feed_restriction(production=live)) # Pick up each library's hyperlinks and validation # information; this will save database queries when building # the feed. alphabetical = alphabetical.options( joinedload('hyperlinks'), joinedload('hyperlinks', 'resource'), joinedload('hyperlinks', 'resource', 'validation'), ) alphabetical = alphabetical.options(defer('logo')) if location is None: # No location data is available. Use the alphabetical list as # the list of libraries. a = time.time() libraries = alphabetical.all() b = time.time() self.log.info( "Built alphabetical list of all libraries in %.2fsec" % (b - a)) else: # Location data is available. Get the list of nearby libraries, then get # the rest of the list in alphabetical order. # We can't easily do the joindeload() thing for this # query, because it doesn't simply return Library objects, # but it won't return more than five results. a = time.time() nearby_libraries = Library.nearby(self._db, location, production=live).limit(5).all() b = time.time() self.log.info("Fetched libraries near %s in %.2fsec" % (location, b - a)) # Exclude nearby libraries from the alphabetical query # to get a list of faraway libraries. faraway_libraries = alphabetical.filter( ~Library.id.in_([x.id for x, distance in nearby_libraries])) c = time.time() libraries = nearby_libraries + faraway_libraries.all() self.log.info("Fetched libraries far from %s in %.2fsec" % (location, c - b)) url = self.app.url_for("libraries_opds") a = time.time() catalog = OPDSCatalog(self._db, 'Libraries', url, libraries, annotator=self.annotator, live=live) b = time.time() self.log.info("Built library catalog in %.2fsec" % (b - a)) return catalog_response(catalog)