Exemple #1
0
def lane_for_other_languages(_db, library, exclude_languages):
    """Make a lane for all books not in one of the given languages."""

    language_lanes = []
    other_languages = Configuration.tiny_collection_languages(library)

    if not other_languages:
        return None

    for language_set in other_languages:
        name = LanguageCodes.name_for_languageset(language_set)
        language_lane = Lane(
            _db,
            library,
            full_name=name,
            genres=None,
            fiction=Lane.BOTH_FICTION_AND_NONFICTION,
            searchable=True,
            languages=language_set,
        )
        language_lanes.append(language_lane)

    lane = Lane(
        _db,
        library,
        full_name="Other Languages",
        sublanes=language_lanes,
        exclude_languages=exclude_languages,
        searchable=True,
        genres=None,
    )
    lane.default_for_language = True
    return lane
Exemple #2
0
    def test_lane_url(self):
        everything_lane = Lane(self._db,
                               "Everything",
                               fiction=Lane.BOTH_FICTION_AND_NONFICTION)

        fantasy_lane_with_sublanes = Lane(self._db,
                                          "Fantasy",
                                          genres=[Fantasy],
                                          languages="eng",
                                          subgenre_behavior=Lane.IN_SAME_LANE,
                                          sublanes=[Urban_Fantasy],
                                          parent=everything_lane)

        fantasy_lane_without_sublanes = Lane(
            self._db,
            "Fantasy",
            genres=[Fantasy],
            languages="eng",
            subgenre_behavior=Lane.IN_SAME_LANE,
            parent=everything_lane)

        default_lane_url = self.annotator.lane_url(everything_lane)
        eq_(default_lane_url, self.annotator.default_lane_url())

        groups_url = self.annotator.lane_url(fantasy_lane_with_sublanes)
        eq_(groups_url, self.annotator.groups_url(fantasy_lane_with_sublanes))

        feed_url = self.annotator.lane_url(fantasy_lane_without_sublanes)
        eq_(feed_url, self.annotator.feed_url(fantasy_lane_without_sublanes))
Exemple #3
0
    def test_language_filter(self):
        script = CacheRepresentationPerLane(self._db, [
            "--language=fre", "--language=English", "--language=none",
            "--min-depth=0"
        ],
                                            testing=True)
        eq_(['fre', 'eng'], script.languages)

        english_lane = Lane(self._db,
                            self._default_library,
                            self._str,
                            languages=['eng'])
        eq_(True, script.should_process_lane(english_lane))

        no_english_lane = Lane(self._db,
                               self._default_library,
                               self._str,
                               exclude_languages=['eng'])
        eq_(True, script.should_process_lane(no_english_lane))

        no_english_or_french_lane = Lane(self._db,
                                         self._default_library,
                                         self._str,
                                         exclude_languages=['eng', 'fre'])
        eq_(False, script.should_process_lane(no_english_or_french_lane))
Exemple #4
0
    def setup(self):
        super(TestOPDS, self).setup()
        parent = Lane(self._db,
                      self._default_library,
                      "Fiction",
                      languages=["eng"],
                      fiction=True)
        self.lane = Lane(self._db,
                         self._default_library,
                         "Fantasy",
                         languages=["eng"],
                         genres=[Fantasy],
                         parent=parent)
        self.annotator = CirculationManagerAnnotator(None,
                                                     self.lane,
                                                     self._default_library,
                                                     test_mode=True)

        # Initialize library with Adobe Vendor ID details
        self._default_library.library_registry_short_name = "FAKE"
        self._default_library.library_registry_shared_secret = "s3cr3t5"

        # A QueryGeneratedLane to test code that handles it differently.
        self.contributor_lane = ContributorLane(self._db,
                                                self._default_library,
                                                "Someone",
                                                languages=["eng"],
                                                audiences=None)
Exemple #5
0
    def setup(self):
        super(TestOPDS, self).setup()
        parent = Lane(self._db, "Fiction", languages=["eng"], fiction=True)
        fantasy_lane = Lane(self._db,
                            "Fantasy",
                            languages=["eng"],
                            genres=[Fantasy],
                            parent=parent)
        self.lane = fantasy_lane

        # A QueryGeneratedLane to test code that handles it differently.
        self.contributor_lane = ContributorLane(self._db,
                                                "Someone",
                                                languages=["eng"],
                                                audiences=None)
Exemple #6
0
    def test_max_and_min_depth(self):
        with self.temp_config() as config:
            script = CacheRepresentationPerLane(
                self._db, ["--max-depth=0", "--min-depth=0"], testing=True)
            eq_(0, script.max_depth)

            child = Lane(self._db, "sublane")
            parent = Lane(self._db, "parent", sublanes=[child])
            eq_(True, script.should_process_lane(parent))
            eq_(False, script.should_process_lane(child))

            script = CacheRepresentationPerLane(self._db, ["--min-depth=1"],
                                                testing=True)
            eq_(1, script.min_depth)
            eq_(False, script.should_process_lane(parent))
            eq_(True, script.should_process_lane(child))
def lane_for_other_languages(_db, exclude_languages):
    """Make a lane for all books not in one of the given languages."""

    YA = Classifier.AUDIENCE_YOUNG_ADULT
    CHILDREN = Classifier.AUDIENCE_CHILDREN

    common_args = dict(
        exclude_languages=exclude_languages,
        genres=None,
    )

    adult_fiction = Lane(
        _db, 
        full_name="Adult Fiction",
        display_name="Fiction",
        fiction=True, 
        audiences=Classifier.AUDIENCES_ADULT,
        **common_args
    )
    adult_nonfiction = Lane(
        _db, full_name="Adult Nonfiction", 
        display_name="Nonfiction",
        fiction=False, 
        audiences=Classifier.AUDIENCES_ADULT,
        **common_args
    )

    ya_children = Lane(
        _db, 
        full_name="Children & Young Adult", 
        fiction=Lane.BOTH_FICTION_AND_NONFICTION,
        audiences=[YA, CHILDREN],
        **common_args
    )

    lane = Lane(
        _db, 
        full_name="Other Languages", 
        sublanes=[adult_fiction, adult_nonfiction, ya_children],
        searchable=True,
        **common_args
    )
    lane.default_for_language = True
    return lane
def lane_for_small_collection(_db, languages):

    YA = Classifier.AUDIENCE_YOUNG_ADULT
    CHILDREN = Classifier.AUDIENCE_CHILDREN

    common_args = dict(
        include_best_sellers=False,
        include_staff_picks=False,
        languages=languages,
        genres=None,
    )

    adult_fiction = Lane(
        _db, full_name="Adult Fiction",
        display_name="Fiction",
        fiction=True, 
        audiences=Classifier.AUDIENCES_ADULT,
        **common_args
    )
    adult_nonfiction = Lane(
        _db, full_name="Adult Nonfiction", 
        display_name="Nonfiction",
        fiction=False, 
        audiences=Classifier.AUDIENCES_ADULT,
        **common_args
    )

    ya_children = Lane(
        _db, 
        full_name="Children & Young Adult", 
        fiction=Lane.BOTH_FICTION_AND_NONFICTION,
        audiences=[YA, CHILDREN],
        **common_args
    )

    name = LanguageCodes.name_for_languageset(languages)
    lane = Lane(
        _db, full_name=name, languages=languages, 
        sublanes=[adult_fiction, adult_nonfiction, ya_children],
        searchable=True
    )
    lane.default_for_language = True
    return lane
Exemple #9
0
 def get_parsed_feed(self, works, lane=None):
     if not lane:
         lane = Lane(self._db, self._default_library, "Main Lane")
     feed = AcquisitionFeed(
         self._db, "test", "url", works,
         CirculationManagerAnnotator(None,
                                     lane,
                                     self._default_library,
                                     test_mode=True))
     return feedparser.parse(unicode(feed))
Exemple #10
0
    def test_process_lane(self):
        lane = Lane(self._db, self._default_library, self._str)

        script = CacheFacetListsPerLane(self._db, [
            "--availability=all", "--availability=always", "--collection=main",
            "--collection=full", "--order=title", "--pages=1"
        ],
                                        testing=True)
        with script.app.test_request_context("/"):
            flask.request.library = self._default_library
            cached_feeds = script.process_lane(lane)
            # 2 availabilities * 2 collections * 1 order * 1 page = 4 feeds
            eq_(4, len(cached_feeds))
Exemple #11
0
    def test_group_uri_with_flattened_lane(self):
        spanish_lane = Lane(self._db, "Spanish", languages="spa")
        flat_spanish_lane = dict({
            "lane": spanish_lane,
            "label": "All Spanish",
            "link_to_list_feed": True
        })
        spanish_work = self._work(title="Spanish Book",
                                  with_license_pool=True,
                                  language="spa")
        lp = spanish_work.license_pools[0]
        self.annotator.lanes_by_work[spanish_work].append(flat_spanish_lane)

        feed_url = self.annotator.feed_url(spanish_lane)
        group_uri = self.annotator.group_uri(spanish_work, lp, lp.identifier)
        eq_((feed_url, "All Spanish"), group_uri)
Exemple #12
0
def lane_for_small_collection(_db, library, languages):

    YA = Classifier.AUDIENCE_YOUNG_ADULT
    CHILDREN = Classifier.AUDIENCE_CHILDREN

    common_args = dict(
        include_best_sellers=False,
        include_staff_picks=False,
        languages=languages,
        genres=None,
    )

    adult_fiction = Lane(_db,
                         library,
                         full_name="Adult Fiction",
                         display_name="Fiction",
                         fiction=True,
                         audiences=Classifier.AUDIENCES_ADULT,
                         **common_args)
    adult_nonfiction = Lane(_db,
                            library,
                            full_name="Adult Nonfiction",
                            display_name="Nonfiction",
                            fiction=False,
                            audiences=Classifier.AUDIENCES_ADULT,
                            **common_args)

    ya_children = Lane(_db,
                       library,
                       full_name="Children & Young Adult",
                       fiction=Lane.BOTH_FICTION_AND_NONFICTION,
                       audiences=[YA, CHILDREN],
                       **common_args)

    name = LanguageCodes.name_for_languageset(languages)
    lane = Lane(_db,
                library,
                full_name=name,
                languages=languages,
                sublanes=[adult_fiction, adult_nonfiction, ya_children],
                searchable=True)
    lane.default_for_language = True
    return lane
Exemple #13
0
def lanes_for_large_collection(_db, library, languages):

    YA = Classifier.AUDIENCE_YOUNG_ADULT
    CHILDREN = Classifier.AUDIENCE_CHILDREN

    common_args = dict(
        languages=languages,
        include_best_sellers=True,
        include_staff_picks=True,
    )

    adult_fiction = Lane(_db,
                         library,
                         full_name="Adult Fiction",
                         display_name="Fiction",
                         genres=None,
                         sublanes=lanes_from_genres(
                             _db,
                             library,
                             fiction_genres,
                             languages=languages,
                             audiences=Classifier.AUDIENCES_ADULT,
                         ),
                         fiction=True,
                         audiences=Classifier.AUDIENCES_ADULT,
                         **common_args)
    adult_nonfiction = Lane(_db,
                            library,
                            full_name="Adult Nonfiction",
                            display_name="Nonfiction",
                            genres=None,
                            sublanes=lanes_from_genres(
                                _db,
                                library,
                                nonfiction_genres,
                                languages=languages,
                                audiences=Classifier.AUDIENCES_ADULT,
                            ),
                            fiction=False,
                            audiences=Classifier.AUDIENCES_ADULT,
                            **common_args)

    ya_common_args = dict(
        audiences=YA,
        languages=languages,
    )

    ya_fiction = Lane(
        _db,
        library,
        full_name="Young Adult Fiction",
        genres=None,
        fiction=True,
        include_best_sellers=True,
        include_staff_picks=True,
        sublanes=[
            Lane(_db,
                 library,
                 full_name="YA Dystopian",
                 display_name="Dystopian",
                 genres=[genres.Dystopian_SF],
                 **ya_common_args),
            Lane(_db,
                 library,
                 full_name="YA Fantasy",
                 display_name="Fantasy",
                 genres=[genres.Fantasy],
                 subgenre_behavior=Lane.IN_SAME_LANE,
                 **ya_common_args),
            Lane(_db,
                 library,
                 full_name="YA Graphic Novels",
                 display_name="Comics & Graphic Novels",
                 genres=[genres.Comics_Graphic_Novels],
                 **ya_common_args),
            Lane(_db,
                 library,
                 full_name="YA Literary Fiction",
                 display_name="Contemporary Fiction",
                 genres=[genres.Literary_Fiction],
                 **ya_common_args),
            Lane(_db,
                 library,
                 full_name="YA LGBTQ Fiction",
                 display_name="LGBTQ Fiction",
                 genres=[genres.LGBTQ_Fiction],
                 **ya_common_args),
            Lane(_db,
                 library,
                 full_name="Mystery & Thriller",
                 genres=[genres.Suspense_Thriller, genres.Mystery],
                 subgenre_behavior=Lane.IN_SAME_LANE,
                 **ya_common_args),
            Lane(_db,
                 library,
                 full_name="YA Romance",
                 display_name="Romance",
                 genres=[genres.Romance],
                 subgenre_behavior=Lane.IN_SAME_LANE,
                 **ya_common_args),
            Lane(_db,
                 library,
                 full_name="YA Science Fiction",
                 display_name="Science Fiction",
                 genres=[genres.Science_Fiction],
                 subgenre_behavior=Lane.IN_SAME_LANE,
                 exclude_genres=[genres.Dystopian_SF, genres.Steampunk],
                 **ya_common_args),
            Lane(_db,
                 library,
                 full_name="YA Steampunk",
                 genres=[genres.Steampunk],
                 subgenre_behavior=Lane.IN_SAME_LANE,
                 display_name="Steampunk",
                 **ya_common_args),
            # TODO:
            # Paranormal -- what is it exactly?
        ],
        **ya_common_args)

    ya_nonfiction = Lane(
        _db,
        library,
        full_name="Young Adult Nonfiction",
        genres=None,
        fiction=False,
        include_best_sellers=True,
        include_staff_picks=True,
        sublanes=[
            Lane(_db,
                 library,
                 full_name="YA Biography",
                 genres=genres.Biography_Memoir,
                 display_name="Biography",
                 **ya_common_args),
            Lane(_db,
                 library,
                 full_name="YA History",
                 genres=[genres.History, genres.Social_Sciences],
                 display_name="History & Sociology",
                 subgenre_behavior=Lane.IN_SAME_LANE,
                 **ya_common_args),
            Lane(_db,
                 library,
                 full_name="YA Life Strategies",
                 display_name="Life Strategies",
                 genres=[genres.Life_Strategies],
                 **ya_common_args),
            Lane(_db,
                 library,
                 full_name="YA Religion & Spirituality",
                 display_name="Religion & Spirituality",
                 genres=genres.Religion_Spirituality,
                 subgenre_behavior=Lane.IN_SAME_LANE,
                 **ya_common_args)
        ],
        **ya_common_args)

    children_common_args = dict(
        audiences=genres.Classifier.AUDIENCE_CHILDREN,
        languages=languages,
    )

    children = Lane(_db,
                    library,
                    full_name="Children and Middle Grade",
                    genres=None,
                    fiction=Lane.BOTH_FICTION_AND_NONFICTION,
                    include_best_sellers=True,
                    include_staff_picks=True,
                    searchable=True,
                    sublanes=[
                        Lane(_db,
                             library,
                             full_name="Picture Books",
                             age_range=[0, 1, 2, 3, 4],
                             genres=None,
                             fiction=Lane.BOTH_FICTION_AND_NONFICTION,
                             **children_common_args),
                        Lane(_db,
                             library,
                             full_name="Easy readers",
                             age_range=[5, 6, 7, 8],
                             genres=None,
                             fiction=Lane.BOTH_FICTION_AND_NONFICTION,
                             **children_common_args),
                        Lane(_db,
                             library,
                             full_name="Chapter books",
                             age_range=[9, 10, 11, 12],
                             genres=None,
                             fiction=Lane.BOTH_FICTION_AND_NONFICTION,
                             **children_common_args),
                        Lane(_db,
                             library,
                             full_name="Children's Poetry",
                             display_name="Poetry books",
                             genres=[genres.Poetry],
                             **children_common_args),
                        Lane(_db,
                             library,
                             full_name="Children's Folklore",
                             display_name="Folklore",
                             genres=[genres.Folklore],
                             subgenre_behavior=Lane.IN_SAME_LANE,
                             **children_common_args),
                        Lane(_db,
                             library,
                             full_name="Children's Fantasy",
                             display_name="Fantasy",
                             fiction=True,
                             genres=[genres.Fantasy],
                             subgenre_behavior=Lane.IN_SAME_LANE,
                             **children_common_args),
                        Lane(_db,
                             library,
                             full_name="Children's SF",
                             display_name="Science Fiction",
                             fiction=True,
                             genres=[genres.Science_Fiction],
                             subgenre_behavior=Lane.IN_SAME_LANE,
                             **children_common_args),
                        Lane(_db,
                             library,
                             full_name="Realistic fiction",
                             fiction=True,
                             genres=[genres.Literary_Fiction],
                             subgenre_behavior=Lane.IN_SAME_LANE,
                             **children_common_args),
                        Lane(_db,
                             library,
                             full_name="Children's Graphic Novels",
                             display_name="Comics & Graphic Novels",
                             genres=[genres.Comics_Graphic_Novels],
                             **children_common_args),
                        Lane(_db,
                             library,
                             full_name="Biography",
                             genres=[genres.Biography_Memoir],
                             subgenre_behavior=Lane.IN_SAME_LANE,
                             **children_common_args),
                        Lane(_db,
                             library,
                             full_name="Historical fiction",
                             genres=[genres.Historical_Fiction],
                             subgenre_behavior=Lane.IN_SAME_LANE,
                             **children_common_args),
                        Lane(_db,
                             library,
                             full_name="Informational books",
                             genres=None,
                             fiction=False,
                             exclude_genres=[genres.Biography_Memoir],
                             subgenre_behavior=Lane.IN_SAME_LANE,
                             **children_common_args)
                    ],
                    **children_common_args)

    name = LanguageCodes.name_for_languageset(languages)
    lane = Lane(_db,
                library,
                full_name=name,
                genres=None,
                sublanes=[
                    adult_fiction, adult_nonfiction, ya_fiction, ya_nonfiction,
                    children
                ],
                fiction=Lane.BOTH_FICTION_AND_NONFICTION,
                searchable=True,
                invisible=True,
                **common_args)

    return [lane]
    def custom_lists(self, identifier_type, identifier):
        self.require_librarian(flask.request.library)

        library = flask.request.library
        work = self.load_work(library, identifier_type, identifier)
        if isinstance(work, ProblemDetail):
            return work

        staff_data_source = DataSource.lookup(self._db,
                                              DataSource.LIBRARY_STAFF)

        if flask.request.method == "GET":
            lists = []
            for entry in work.custom_list_entries:
                list = entry.customlist
                lists.append(dict(id=list.id, name=list.name))
            return dict(custom_lists=lists)

        if flask.request.method == "POST":
            lists = flask.request.form.get("lists")
            if lists:
                lists = json.loads(lists)
            else:
                lists = []

            affected_lanes = set()

            # Remove entries for lists that were not in the submitted form.
            submitted_ids = [l.get("id") for l in lists if l.get("id")]
            for entry in work.custom_list_entries:
                if entry.list_id not in submitted_ids:
                    list = entry.customlist
                    list.remove_entry(work)
                    for lane in Lane.affected_by_customlist(list):
                        affected_lanes.add(lane)

            # Add entries for any new lists.
            for list_info in lists:
                id = list_info.get("id")
                name = list_info.get("name")

                if id:
                    is_new = False
                    list = get_one(self._db,
                                   CustomList,
                                   id=int(id),
                                   name=name,
                                   library=library,
                                   data_source=staff_data_source)
                    if not list:
                        self._db.rollback()
                        return MISSING_CUSTOM_LIST.detailed(
                            _("Could not find list \"%(list_name)s\"",
                              list_name=name))
                else:
                    list, is_new = create(self._db,
                                          CustomList,
                                          name=name,
                                          data_source=staff_data_source,
                                          library=library)
                    list.created = datetime.now()
                entry, was_new = list.add_entry(work, featured=True)
                if was_new:
                    for lane in Lane.affected_by_customlist(list):
                        affected_lanes.add(lane)

            # If any list changes affected lanes, update their sizes.
            # NOTE: This may not make a difference until the
            # works are actually re-indexed.
            for lane in affected_lanes:
                lane.update_size(self._db, self.search_engine)

            return Response(unicode(_("Success")), 200)