Exemple #1
0
 def setUp(self):
     self.repo = Repo(autocommit=True)
     self.release_processor = ReleaseProcessor(repo=self.repo)
     self.user = UserFactory(email="*****@*****.**")
     self.artist = ArtistFactory(
         name="Tulsa", mbid="f123ef70-f563-43c2-b0e6-8f9afc0a38ad")
     self.user_artist = UserArtistFactory(user=self.user,
                                          artist=self.artist)
     self.repo.save(self.user, self.artist)
def run_command():
    repo = Repo()
    limit = 200
    numu_app.logger.info("Starting MB process...")

    # Scan user imports
    imports_processed = ImportProcessor(repo=repo).import_user_artists(
        check_musicbrainz=True)

    # If imports have been taken care of, update artists and releases.
    if imports_processed == 0:
        # Scan artists
        date_offset = datetime.now() - timedelta(days=3)
        artists = (Artist.query.filter(
            or_(Artist.date_checked < date_offset,
                Artist.date_checked.is_(None))).order_by(
                    Artist.date_checked.asc().nullsfirst()).limit(limit).all())

        for artist in artists:
            numu_app.logger.info("Updating Artist: {} - Last check: {}".format(
                artist, artist.date_checked))
            updated_artist = ArtistProcessor(repo=repo).update_artist(artist)
            if updated_artist:
                releases_added = ReleaseProcessor().add_releases(
                    updated_artist)
                numu_app.logger.info(
                    "Added Releases: {}".format(releases_added))

        repo.commit()

        # Scan releases
        date_offset = datetime.now() - timedelta(days=14)
        releases = (Release.query.filter(
            Release.date_checked < date_offset).order_by(
                Release.date_checked.asc()).limit(limit).all())

        for release in releases:
            numu_app.logger.info(
                "Updating Release: {} - Last check: {}".format(
                    release, release.date_checked))
            release = ReleaseProcessor(repo=repo).update_release(release)
            if release:
                # If release was deleted, it'll be None by the time we get here.
                release.date_checked = utils.now()
                repo.save(release)
        repo.commit()
 def __init__(self, repo=None, mbz=None):
     self.repo = repo or Repo()
     self.mbz = mbz or musicbrainz
     self.logger = numu_app.logger
     self.artist_processor = ArtistProcessor(repo=repo, mbz=self.mbz)
     self.release_processor = ReleaseProcessor(repo=repo, mbz=self.mbz)
class ImportProcessor:
    def __init__(self, repo=None, mbz=None):
        self.repo = repo or Repo()
        self.mbz = mbz or musicbrainz
        self.logger = numu_app.logger
        self.artist_processor = ArtistProcessor(repo=repo, mbz=self.mbz)
        self.release_processor = ReleaseProcessor(repo=repo, mbz=self.mbz)

    def import_from_lastfm(self,
                           user_id,
                           lastfm_username,
                           limit=500,
                           period="overall",
                           page=1):
        """Download artists from a LastFM account into the user's library.

        Period options: overall | 7day | 1month | 3month | 6month | 12month"""

        data = utils.grab_json(
            "http://ws.audioscrobbler.com/2.0/?method=user.gettopartists" +
            "&user={}&limit={}&api_key={}&period={}&page={}&format=json".
            format(
                lastfm_username,
                limit,
                numu_app.config.get("LAST_FM_API_KEY"),
                period,
                page,
            ))
        artists_list = []
        for artist in data.get("topartists", {}).get("artist"):
            artists_list.append({
                "name": artist["name"],
                "mbid": artist["mbid"]
            })

        return self.save_imports(user_id, artists_list, import_method="lastfm")

    def save_imports(self, user_id, artists_list, import_method):
        validated_artists = []
        for artist in artists_list:
            try:
                artist_name = str(
                    artist["name"]) if artist.get("name") else None
                artist_mbid = str(
                    artist["mbid"]) if artist.get("mbid") else None
                if artist_name or artist_mbid:
                    validated_artists.append({
                        "name": artist_name,
                        "mbid": artist_mbid
                    })
            except ValueError:
                pass

        if len(validated_artists) == 0:
            return 0

        artists_added = 0

        for artist in validated_artists:
            found_import = self.repo.get_artist_import(user_id,
                                                       name=artist["name"],
                                                       mbid=artist["mbid"])
            if found_import is None:
                new_import = UserArtistImport(
                    user_id=user_id,
                    import_name=artist["name"],
                    import_mbid=artist["mbid"],
                    import_method=import_method,
                )
                self.repo.save(new_import)
                artists_added += 1

        if artists_added > 0:
            self.repo.commit()
            self.import_user_artists(False, user_id)

        return artists_added

    def import_user_artists(self, check_musicbrainz=True, user_id=None):
        imports_processed = 0
        date_filter = datetime.now() - timedelta(days=14)
        limit = 5000
        if check_musicbrainz:
            limit = 1000

        if user_id:
            artist_imports = self.repo.get_user_artist_imports(user_id)
        else:
            artist_imports = self.repo.get_artist_imports(date_filter, limit)

        for artist_import in artist_imports:
            found_artist = self._find_artist(artist_import, check_musicbrainz)

            if found_artist is not None:
                self.logger.info("Found artist {}".format(found_artist))
                user_artist = self._create_user_artist(
                    artist_import.user_id, artist_import.import_method,
                    found_artist)
                if check_musicbrainz:
                    artist_import.found_mbid = found_artist.mbid
                    self._create_user_releases(found_artist, user_artist)
            else:
                self.logger.info("Did not find artist")
                if check_musicbrainz:
                    artist_import.date_checked = func.now()

            imports_processed += 1
            self.repo.save(artist_import)
            self.repo.commit()
        return imports_processed

    def _find_artist(self, artist_import, check_musicbrainz):
        found_artist = None
        self.logger.info("Checking artist import {} - {}".format(
            artist_import.user_id, artist_import.import_name))

        self.logger.info("Searching by MBID")
        found_artist = self.repo.get_artist_by_mbid(artist_import.import_mbid)

        if found_artist is None:
            self.logger.info("Searching by name")
            found_artist = self.repo.get_artist_by_name(
                artist_import.import_name)

        if found_artist is None and check_musicbrainz:
            self.logger.info("Searching MusicBrainz")
            found_artist = self.artist_processor.add_artist(
                name=artist_import.import_name, mbid=artist_import.import_mbid)
            if found_artist:
                self.release_processor.add_releases(found_artist)

        return found_artist

    def _create_user_artist(self, user_id, import_method, artist):
        user_artist = self.artist_processor.add_user_artist(
            user_id, artist, import_method)
        return user_artist

    def _create_user_releases(self, artist, user_artist):
        self.release_processor.update_user_releases(artist, user_artist, False)
Exemple #5
0
class TestReleases(BaseTestCase):
    def setUp(self):
        self.repo = Repo(autocommit=True)
        self.release_processor = ReleaseProcessor(repo=self.repo)
        self.user = UserFactory(email="*****@*****.**")
        self.artist = ArtistFactory(
            name="Tulsa", mbid="f123ef70-f563-43c2-b0e6-8f9afc0a38ad")
        self.user_artist = UserArtistFactory(user=self.user,
                                             artist=self.artist)
        self.repo.save(self.user, self.artist)

    def test_add_release_from_mb(self):
        releases_added = self.release_processor.add_releases(self.artist)
        self.release_processor.update_user_releases(self.artist)

        user_releases = self.repo.get_user_releases_for_artist(
            self.user, self.artist.mbid)

        assert releases_added == 1
        assert len(user_releases) == 1

    def test_update_release_no_update(self):
        """When a release is updated with identical information, date_checked should update but not date_updated."""
        self.release_processor.add_release(
            "dd5d8373-4ae3-3908-9235-c871e49ebd76")
        release = self.repo.get_release_by_mbid(
            "dd5d8373-4ae3-3908-9235-c871e49ebd76")

        updated_release = self.release_processor.update_release(release)

        assert updated_release.date_updated != updated_release.date_checked

    def test_update_release_with_mock(self):
        release = ReleaseFactory(artist_names=self.artist.name)
        release.artists.append(self.artist)
        user_release = UserReleaseFactory(user=self.user, release=release)

        self.repo.save(user_release)

        mb_release = {
            "first-release-date": "2015-01-01",
            "title": "Random Title",
            "artist-credit-phrase": "Tulsa",
            "primary-type": "Album",
            "artist-credit": [{
                "artist": {}
            }],
        }

        self.release_processor._update_release(release, mb_release)

        release = self.repo.get_release_by_mbid(release.mbid)
        assert release.title == "Random Title"

        user_release = self.repo.get_user_release(self.user.id, release.mbid)
        assert user_release.release.title == "Random Title"

    def test_update_release_with_mock_delete(self):
        release = ReleaseFactory(artist_names=self.artist.name)
        release.artists.append(self.artist)
        self.repo.save(release)

        mb_release = {
            "first-release-date": "2015-01-01",
            "title": "Random Title",
            "artist-credit-phrase": "Tulsa",
            "primary-type": "Album",
        }

        self.release_processor._update_release(release, mb_release)

        release = self.repo.get_release_by_mbid(release.mbid)

        assert release is None

    def test_update_release_from_mb_with_followers_and_listeners(self):
        pass

    def test_delete_release_with_listeners(self):
        pass
def import_numu_v2():
    """
    Import data from Numu API v2
    Imports:
    - artists
    - listening history
    - filters
    """
    user = g.user
    repo = Repo()
    import_processor = ImportProcessor()
    release_processor = ReleaseProcessor()
    username = user.email if user.email else user.icloud

    result = {}

    data = grab_json(
        "https://www.numutracker.com/v2/json2.php?importv2={}&key={}".format(
            username, numu_app.config.get("NUMU_V2_API_KEY")
        )
    )

    result["raw_data"] = data

    filters = data.get("filters")
    if filters:
        user.album = bool(filters["album"])
        user.ep = bool(filters["ep"])
        user.single = bool(filters["single"])
        user.live = bool(filters["live"])
        user.soundtrack = bool(filters["soundtrack"])
        user.remix = bool(filters["remix"])
        user.other = bool(filters["other"])
        repo.save(user)
        repo.commit()

    artists = data.get("artists")
    if artists:
        imported = import_processor.save_imports(user.id, artists, "v2")
        result["artists_imported"] = imported

    listens = data.get("listens")
    if listens:
        releases_added = 0
        for listen in listens:
            release_mbid = listen.get("mbid")
            release = release_processor.add_release(release_mbid)

            if release:
                user_release, notify = release_processor.add_user_release(
                    release, user_id=user.id
                )
                user_release.listened = True
                user_release.date_listened = listen.get("listen_date")
                repo.save(user_release)
                if notify:
                    releases_added += 1
        repo.commit()

        result["releases_added"] = releases_added

    return response.success(result)
from backend import utils
from backend.models import Lock, User
from backend.repo import Repo
from backend.user_artists import ImportProcessor
from backend.releases import ReleaseProcessor
from numu import app as numu_app

repo = Repo()
import_processor = ImportProcessor(repo=repo)
release_processor = ReleaseProcessor(repo=repo)


@numu_app.cli.command()
def import_user_data():
    """Import user data from V2 automatically."""
    process_name = "import_user_data"
    lock = Lock.query.filter_by(process_name=process_name).first()
    if lock is None:
        lock = Lock(process_name=process_name, lock_acquired=False)
    if lock.lock_acquired is False:
        lock.lock_acquired = True
        lock.date_acquired = utils.now()
        repo.save(lock)
        repo.commit()

        run_command()

        lock.lock_acquired = False
        repo.save(lock)
        repo.commit()
    else: