Beispiel #1
0
    def do_push_artists(self):
        # patch credentials
        if not request.headers.get('Authorization'):
            abort(401)
        else:
            auth = request.headers['Authorization'].lstrip('Basic ')
            username, password = base64.b64decode(auth).split(':')
            if username and password:
                conf.CHIRPRADIO_AUTH = '%s %s' % (username, password)
                chirpradio.connect()
            else:
                abort(401)

        dry_run = False

        # reload artists from file
        artists._init()

        # Find all of the library artists
        all_library_artists = set(artists.all())

        # Find all of the artists in the cloud.
        all_chirpradio_artists = set()
        mapped = 0
        t1 = time.time()
        for art in models.Artist.fetch_all():
            if art.revoked:
                continue
            std_name = artists.standardize(art.name)
            if std_name != art.name:
                #print "Mapping %d: %s => %s" % (mapped, art.name, std_name)
                mapped += 1
                art.name = std_name
                idx = search.Indexer()
                idx._transaction = art.parent_key()
                idx.add_artist(art)
                if not dry_run:
                    idx.save()
            all_chirpradio_artists.add(art.name)

        to_push = list(all_library_artists.difference(all_chirpradio_artists))

        Messages.add_message("Pushing %d artists" % len(to_push), 'warning')
        while to_push:
            # Push the artists in batches of 50
            this_push = to_push[:50]
            to_push = to_push[50:]
            idx = search.Indexer()
            for name in this_push:
                #print name
                art = models.Artist.create(parent=idx.transaction, name=name)
                idx.add_artist(art)
            if not dry_run:
                idx.save()
            #print "+++++ Indexer saved"

        Messages.add_message("Artist push complete. OK!", 'success')
Beispiel #2
0
def modify_tags_and_save(user, obj, to_add, to_remove):
    """Modify the set of tags attached to an object, and save to the datastore.

    Args:
      user: The User object of the person responsible for this change
        to the tags.
      obj: The object (either an Album or a Track) containing the tags.
      to_add: A sequence of tags to add to the object.
      to_remove: A sequence of tags to remove from the object.

    Returns:
      True if a modified version of the object was saved, or False if
      no changes were necessary.
    """
    to_add = list(set(to_add).difference(obj.current_tags))
    to_remove = list(set(to_remove).intersection(obj.current_tags))
    if not (to_add or to_remove):
        return False
    obj.current_tags = list(
        set(obj.current_tags).union(to_add).difference(to_remove))
    tag_edit = models.TagEdit(parent=obj, subject=obj, author=user,
                              added=to_add, removed=to_remove)
    # The two objects are in the same entity group, so saving them
    # is an all-or-nothing operation.
    AutoRetry(db).save([obj, tag_edit])
    
    # Update search indexer.
    idx = search.Indexer(obj.parent_key())
    for tag in to_remove:
        idx.remove_key(obj.key(), 'tag', tag)
    for tag in to_add:
        idx.add_key(obj.key(), 'tag', tag)
    idx.save()
    
    return True
def main_generator():
    chirpradio.connect()

    dry_run = False

    # Find all of the library artists
    all_library_artists = set(artists.all())

    # Find all of the artists in the cloud.
    all_chirpradio_artists = set()
    mapped = 0
    t1 = time.time()
    for art in models.Artist.fetch_all():
        if art.revoked:
            continue
        std_name = artists.standardize(art.name)
        if std_name != art.name:
            cprint(u"Mapping {}: {} => {}".format(mapped, art.name, std_name))
            mapped += 1
            art.name = std_name
            idx = search.Indexer()
            idx._transaction = art.parent_key()
            idx.add_artist(art)
            if not dry_run:
                idx.save()
        all_chirpradio_artists.add(art.name)
        yield

    to_push = list(all_library_artists.difference(all_chirpradio_artists))

    cprint("Pushing %d artists" % len(to_push))
    while to_push:
        # Push the artists in batches of 50
        this_push = to_push[:50]
        to_push = to_push[50:]
        idx = search.Indexer()
        for name in this_push:
            cprint(name)
            art = models.Artist.create(parent=idx.transaction, name=name)
            idx.add_artist(art)
        if not dry_run:
            idx.save()
        cprint("+++++ Indexer saved")
        yield
Beispiel #4
0
def main():
    parser = optparse.OptionParser(usage='%prog')
    parser.add_option('--clear-datastore', action='store_true')
    (options, args) = parser.parse_args()

    startup_appengine(clear_datastore=options.clear_datastore)

    from djdb import search, models
    import datetime

    idx = search.Indexer()

    # Create some test artists.
    art1 = models.Artist(name=u"Fall, The",
                         parent=idx.transaction,
                         key_name="art1")
    art2 = models.Artist(name=u"Eno, Brian",
                         parent=idx.transaction,
                         key_name="art2")
    # Create some test albums.
    alb1 = models.Album(title=u"This Nation's Saving Grace",
                        album_id=12345,
                        import_timestamp=datetime.datetime.now(),
                        album_artist=art1,
                        num_tracks=123,
                        parent=idx.transaction)
    alb2 = models.Album(title=u"Another Green World",
                        album_id=67890,
                        import_timestamp=datetime.datetime.now(),
                        album_artist=art2,
                        num_tracks=456,
                        parent=idx.transaction)
    for i, track_title in enumerate(
        (u"Spider And I", u"Running To Tie Your Shoes", u"Kings Lead Hat")):
        idx.add_track(
            models.Track(ufid="test3-%d" % i,
                         album=alb2,
                         sampling_rate_hz=44110,
                         bit_rate_kbps=128,
                         channels="mono",
                         duration_ms=789,
                         title=track_title,
                         track_artist=art2,
                         track_num=i + 1,
                         parent=idx.transaction))
    idx.add_artist(art1)
    idx.add_artist(art2)
    idx.add_album(alb1)
    idx.add_album(alb2)

    idx.save()  # saves all objects

    print "created some artists and stuff"
Beispiel #5
0
    def test_basic_indexing_and_search(self):
        key1 = db.Key.from_path("kind_Foo", "key1")
        key2 = db.Key.from_path("kind_Foo", "key2")
        key3 = db.Key.from_path("kind_Bar", "key3")
        key4 = db.Key.from_path("kind_Bar", "key4")

        idx = search.Indexer()
        idx.add_key(key1, "f1", u"alpha beta")
        idx.add_key(key2, "f2", u"alpha delta")
        idx.save()

        idx = search.Indexer()
        idx.add_key(key3, "f1", u"alpha gamma")
        idx.add_key(key4, "f2", u"alaska")
        idx.save()

        self.assertEqual(set([(key1, "f1"), (key2, "f2"), (key3, "f1")]),
                         search.fetch_keys_for_one_term("alpha"))

        self.assertEqual(
            set([(key1, "f1"), (key2, "f2")]),
            search.fetch_keys_for_one_term("alpha", entity_kind="kind_Foo"))

        self.assertEqual(set([(key1, "f1"), (key3, "f1")]),
                         search.fetch_keys_for_one_term("alpha", field="f1"))

        self.assertEqual(set([(key1, "f1")]),
                         search.fetch_keys_for_one_term("beta"))

        self.assertEqual(0, len(search.fetch_keys_for_one_term("unknown")))

        self.assertEqual(set([(key1, "f1"), (key2, "f2"), (key3, "f1")]),
                         search.fetch_keys_for_one_prefix("alpha"))
        self.assertEqual(
            set([(key1, "f1"), (key2, "f2"), (key3, "f1"), (key4, "f2")]),
            search.fetch_keys_for_one_prefix("al"))
        self.assertEqual(set([(key2, "f2"), (key4, "f2")]),
                         search.fetch_keys_for_one_prefix("al", field="f2"))

        self.assertEqual(0, len(search.fetch_keys_for_one_prefix("unknown")))
Beispiel #6
0
 def flush(list_of_pending_albums):
     if not list_of_pending_albums:
         return
     idx = search.Indexer()
     for alb in list_of_pending_albums:
         process_one_album(idx, alb)
     # This runs as a batch job, so set a very long deadline.
     while True:
         try:
             rpc = db.create_rpc(deadline=120)
             idx.save(rpc=rpc)
             return
         except urllib2.URLError:
             #print "Retrying indexer flush"
             pass
Beispiel #7
0
 def setUp(self):
     idx = search.Indexer()
     # Create some test artists.
     art = models.Artist(name=u"beatles",
                         parent=idx.transaction,
                         key_name="ss-art1")
     idx.add_artist(art)
     art = models.Artist(name=u"beatnicks",
                         parent=idx.transaction,
                         key_name="ss-art2")
     idx.add_artist(art)
     art = models.Artist(name=u"beatnuts",
                         parent=idx.transaction,
                         key_name="ss-art3")
     idx.add_artist(art)
     idx.save()
Beispiel #8
0
def bootstrap(request):
    """Inject test library data into the datastore."""
    # We never want to do this in prod!
    if in_prod():
        return http.HttpResponse(status=403)
    # First, inject the artist names.
    search.create_artists(_ARTIST_NAMES)
    # Now build up a bunch of random albums for each artist.
    counter = 1
    for art in models.Artist.all().fetch(100):
        for _ in range(random.randint(1, 10)):

            # 10% are multi-disc sets
            discs = [None]
            if random.randint(1, 10) == 1:
                discs = range(1, random.randint(2, 5))

            idx = search.Indexer()
            for disc_num in discs:
                counter += 1
                alb = models.Album(
                    title=random_phrase(),
                    #label=_LABELS[random.randint(0, len(_LABELS) - 1)],
                    #year=_YEARS[random.randint(0, len(_YEARS) - 1)],
                    disc_number=disc_num,
                    album_id=counter,
                    import_timestamp=datetime.datetime.now(),
                    album_artist=art,
                    num_tracks=random.randint(2, 12),
                    parent=idx.transaction,
                )
                idx.add_album(alb)
                for i in range(alb.num_tracks):
                    trk = models.Track(ufid="%d:%d" % (counter, i),
                                       album=alb,
                                       title=random_phrase(),
                                       track_num=i + 1,
                                       sampling_rate_hz=44100,
                                       bit_rate_kbps=128,
                                       channels=u"stereo",
                                       duration_ms=random.randint(
                                           60000, 300000),
                                       parent=idx.transaction)
                    idx.add_track(trk)
            idx.save()
    return http.HttpResponseRedirect("/djdb/")
Beispiel #9
0
    def test_object_indexing(self):
        idx = search.Indexer()

        # Create some test artists.
        art1 = models.Artist(name=u"Fall, The",
                             parent=idx.transaction,
                             key_name="art1")
        art2 = models.Artist(name=u"Eno, Brian",
                             parent=idx.transaction,
                             key_name="art2")
        # Create some test single-artist albums.
        alb1 = models.Album(title=u"This Nation's Saving Grace",
                            year=1985,
                            album_id=12345,
                            label=u"Some Label",
                            import_timestamp=datetime.datetime.now(),
                            album_artist=art1,
                            num_tracks=123,
                            parent=idx.transaction)
        trk1 = []
        for i, track_title in enumerate(
            (u"Mansion", u"Bombast", u"Cruiser's Creek", u"What You Need",
             u"Spoiled Victorian Child", u"L.A.")):
            trk1.append(
                models.Track(ufid="test1-%d" % i,
                             album=alb1,
                             sampling_rate_hz=44110,
                             bit_rate_kbps=320,
                             channels="stereo",
                             duration_ms=123,
                             title=track_title,
                             track_num=i + 1,
                             parent=idx.transaction))
        alb2 = models.Album(title=u"Another Green World",
                            album_id=67890,
                            label=u"Some Label",
                            import_timestamp=datetime.datetime.now(),
                            album_artist=art2,
                            num_tracks=456,
                            parent=idx.transaction)
        trk2 = []
        for i, track_title in enumerate(
            (u"Sky Saw", u"Over Fire Island", u"St. Elmo's Fire",
             u"In Dark Trees", u"The Big Ship")):
            trk2.append(
                models.Track(ufid="test2-%d" % i,
                             album=alb2,
                             sampling_rate_hz=44110,
                             bit_rate_kbps=192,
                             channels="joint_stereo",
                             duration_ms=456,
                             title=track_title,
                             track_num=i + 1,
                             parent=idx.transaction))
        # Create a test album that is a compilation.
        alb3 = models.Album(title=u"R&B Gold: 1976",
                            album_id=76543,
                            label=u"Some Label",
                            import_timestamp=datetime.datetime.now(),
                            is_compilation=True,
                            num_tracks=789,
                            parent=idx.transaction)
        trk3_art = []
        trk3 = []
        for i, (artist_name, track_title) in enumerate(
            ((u"Earth, Wind & Fire", u"Sing A Song"),
             (u"Diana Ross", u"Love Hangover"), (u"Aretha Franklin",
                                                 u"Something He Can Feel"),
             (u"KC & the Sunshine Band",
              u"(Shake, Shake, Shake) Shake Your Booty"))):
            art = models.Artist(name=artist_name,
                                key_name=artist_name,
                                parent=idx.transaction)
            trk3_art.append(art)
            trk3.append(
                models.Track(ufid="test3-%d" % i,
                             album=alb3,
                             sampling_rate_hz=44110,
                             bit_rate_kbps=128,
                             channels="mono",
                             duration_ms=789,
                             title=track_title,
                             track_artist=art,
                             track_num=i + 1,
                             parent=idx.transaction))

        # Now index everything we just created.
        idx.add_artist(art1)
        idx.add_artist(art2)
        for art in trk3_art:
            idx.add_artist(art)

        idx.add_album(alb1)
        idx.add_album(alb2)
        idx.add_album(alb3)

        for trk in trk1 + trk2 + trk3:
            idx.add_track(trk)

        idx.save()  # This also saves all of the objects.

        # Now do some test searches.

        # This query matches the album and all of the tracks.
        expected = {alb1.key(): set(["title"])}
        self.assertEqual(
            expected,
            search.fetch_keys_for_query_string(u"nations",
                                               entity_kind="Album"))
        for t in trk1:
            expected[t.key()] = set(["album"])
        self.assertEqual(expected,
                         search.fetch_keys_for_query_string(u"nations"))

        # The query "fire" should match:
        #   * Two of the songs from "Another Green World"
        #   * The band "Earth, Wind & Fire"
        #   * The EW&F track from the compilation.
        expected = {
            trk2[1].key(): set(["title"]),
            trk2[2].key(): set(["title"]),
            trk3_art[0].key(): set(["name"]),
            trk3[0].key(): set(["artist"]),
        }
        self.assertEqual(expected, search.fetch_keys_for_query_string(u"fire"))
Beispiel #10
0
    def test_search_using_queries(self):
        key1 = db.Key.from_path("kind_Foo", "key1")
        key2 = db.Key.from_path("kind_Foo", "key2")
        key3 = db.Key.from_path("kind_Foo", "key3")
        key4 = db.Key.from_path("kind_Bar", "key4")
        key5 = db.Key.from_path("kind_Bar", "key5")
        key6 = db.Key.from_path("kind_Bar", "key6")
        key7 = db.Key.from_path("kind_Bar", "key7")

        idx = search.Indexer()
        idx.add_key(key1, "f1", u"alpha beta")
        idx.add_key(key2, "f2", u"alpha delta")
        idx.add_key(key3, "f1", u"alaska beta")
        idx.add_key(key4, "f2", u"beta delta")
        idx.add_key(key5, "f1", u"alpha alaska")
        idx.add_key(key6, "f2", u"delta gamma")
        # an indexed value ending in a stop word:
        idx.add_key(key7, "stop-word-prefix", u"something in")
        idx.save()

        # Check that some simple queries are handled correctly.
        self.assertEqual(
            {
                key1: set(["f1"]),
                key2: set(["f2"]),
                key5: set(["f1"])
            }, search.fetch_keys_for_query_string(u"alpha"))
        self.assertEqual(
            {
                key2: set(["f2"]),
                key4: set(["f2"]),
                key6: set(["f2"])
            }, search.fetch_keys_for_query_string(u"delta"))
        self.assertEqual(
            {
                key1: set(["f1"]),
                key2: set(["f2"]),
                key3: set(["f1"]),
                key5: set(["f1"])
            }, search.fetch_keys_for_query_string(u"al*"))
        self.assertEqual({key1: set(["f1"])},
                         search.fetch_keys_for_query_string(u"beta alpha"))
        self.assertEqual({
            key1: set(["f1"]),
            key3: set(["f1"])
        }, search.fetch_keys_for_query_string(u"al* beta"))
        self.assertEqual({
            key2: set(["f2"]),
            key5: set(["f1"])
        }, search.fetch_keys_for_query_string(u"al* -beta"))
        self.assertEqual({
            key4: set(["f2"]),
            key6: set(["f2"])
        }, search.fetch_keys_for_query_string(u"delta -al*"))
        # Make sure we can run a prefix search on a stop word
        # (this is necessary for autocomplete searches)
        self.assertEqual({key7: set(["stop-word-prefix"])},
                         search.fetch_keys_for_query_string(u"something i*"))

        # Check that entity kind restrictions are respected.
        self.assertEqual({
            key1: set(["f1"]),
            key2: set(["f2"])
        }, search.fetch_keys_for_query_string(u"alpha",
                                              entity_kind="kind_Foo"))
        self.assertEqual({key5: set(["f1"])},
                         search.fetch_keys_for_query_string(
                             u"al*", entity_kind="kind_Bar"))
        self.assertEqual({key2: set(["f2"])},
                         search.fetch_keys_for_query_string(
                             u"al* -beta", entity_kind="kind_Foo"))

        # Check that searches against unknown terms are handled properly.
        self.assertEqual({}, search.fetch_keys_for_query_string(u"nosuchterm"))
        self.assertEqual({},
                         search.fetch_keys_for_query_string(u"nosuchterm*"))
        self.assertEqual(
            {}, search.fetch_keys_for_query_string(u"alpha nosuchterm"))
        self.assertEqual(
            {}, search.fetch_keys_for_query_string(u"alpha nosuchterm*"))
        self.assertEqual(
            {
                key1: set(["f1"]),
                key2: set(["f2"]),
                key5: set(["f1"])
            }, search.fetch_keys_for_query_string(u"alpha -nosuchterm"))
        self.assertEqual(
            {
                key1: set(["f1"]),
                key2: set(["f2"]),
                key5: set(["f1"])
            }, search.fetch_keys_for_query_string(u"alpha -nosuchterm*"))

        # Check that None is returned for various invalid/bogus queries.
        self.assertEqual(None, search.fetch_keys_for_query_string(u""))
        self.assertEqual(None, search.fetch_keys_for_query_string(u"+,,,*"))
        self.assertEqual(None, search.fetch_keys_for_query_string(u"-foo"))